1 #pragma once 2 #include "evdev.hpp" 3 4 #include <systemd/sd-event.h> 5 6 #include <experimental/filesystem> 7 #include <string> 8 9 namespace phosphor 10 { 11 namespace gpio 12 { 13 namespace presence 14 { 15 16 static constexpr auto deviceField = 0; 17 static constexpr auto pathField = 1; 18 using Device = std::string; 19 using Path = std::experimental::filesystem::path; 20 using Driver = std::tuple<Device, Path>; 21 using Interface = std::string; 22 23 /** @class Presence 24 * @brief Responsible for determining and monitoring presence, 25 * by monitoring GPIO state changes, of inventory items and 26 * updating D-Bus accordingly. 27 */ 28 class Presence : public Evdev 29 { 30 31 using Property = std::string; 32 using Value = std::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>; 41 42 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; 49 50 /** @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 61 * @param[in] ifaces - list of extra interfaces to associate with the 62 * inventory item 63 * @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, 70 const std::vector<Interface>& ifaces, 71 sd_event_io_handler_t handler = Presence::processEvents) : 72 Evdev(path, key, event, handler, true), 73 bus(bus), inventory(inventory), name(name), drivers(drivers), 74 ifaces(ifaces) 75 { 76 determinePresence(); 77 } 78 79 /** @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); 91 92 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); 99 100 /** 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); 108 109 /** @brief Connection for sdbusplus bus */ 110 sdbusplus::bus::bus& bus; 111 112 /** 113 * @brief Read the GPIO device to determine initial presence and set 114 * present property at D-Bus path. 115 */ 116 void determinePresence(); 117 118 /** @brief Object path under inventory to display this inventory item */ 119 const std::string inventory; 120 121 /** @brief Pretty name of the inventory item*/ 122 const std::string name; 123 124 /** @brief Analyzes the GPIO event and update present property*/ 125 void analyzeEvent(); 126 127 /** @brief Vector of path and device tuples to bind/unbind*/ 128 const std::vector<Driver> drivers; 129 130 /** @brief Vector of extra inventory interfaces to associate with the 131 * inventory item 132 */ 133 const std::vector<Interface> ifaces; 134 135 /** 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); 148 }; 149 150 /** 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 */ 160 std::string getService(const std::string& path, const std::string& interface, 161 sdbusplus::bus::bus& bus); 162 163 } // namespace presence 164 } // namespace gpio 165 } // namespace phosphor 166