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 22 /** @class Presence 23 * @brief Responsible for determining and monitoring presence, 24 * by monitoring GPIO state changes, of inventory items and 25 * updating D-Bus accordingly. 26 */ 27 class Presence : public Evdev 28 { 29 30 using Property = std::string; 31 using Value = sdbusplus::message::variant<bool, std::string>; 32 // Association between property and its value 33 using PropertyMap = std::map<Property, Value>; 34 using Interface = std::string; 35 // Association between interface and the D-Bus property 36 using InterfaceMap = std::map<Interface, PropertyMap>; 37 using Object = sdbusplus::message::object_path; 38 // Association between object and the interface 39 using ObjectMap = std::map<Object, InterfaceMap>; 40 41 public: 42 Presence() = delete; 43 ~Presence() = default; 44 Presence(const Presence&) = delete; 45 Presence& operator=(const Presence&) = delete; 46 Presence(Presence&&) = delete; 47 Presence& operator=(Presence&&) = delete; 48 49 /** @brief Constructs Presence object. 50 * 51 * @param[in] bus - D-Bus bus Object 52 * @param[in] inventory - Object path under inventory 53 to display this inventory item 54 * @param[in] path - Device path to read for GPIO pin state 55 to determine presence of inventory item 56 * @param[in] key - GPIO key to monitor 57 * @param[in] name - Pretty name of the inventory item 58 * @param[in] event - sd_event handler 59 * @param[in] drivers - list of device drivers to bind and unbind 60 * @param[in] handler - IO callback handler. Defaults to one in this 61 * class 62 */ 63 Presence(sdbusplus::bus::bus& bus, const std::string& inventory, 64 const std::string& path, const unsigned int key, 65 const std::string& name, EventPtr& event, 66 const std::vector<Driver>& drivers, 67 sd_event_io_handler_t handler = Presence::processEvents) : 68 Evdev(path, key, event, handler, true), 69 bus(bus), inventory(inventory), name(name), drivers(drivers) 70 { 71 determinePresence(); 72 } 73 74 /** @brief Callback handler when the FD has some activity on it 75 * 76 * @param[in] es - Populated event source 77 * @param[in] fd - Associated File descriptor 78 * @param[in] revents - Type of event 79 * @param[in] userData - User data that was passed during registration 80 * 81 * @return - 0 or positive number on success and negative 82 * errno otherwise 83 */ 84 static int processEvents(sd_event_source* es, int fd, uint32_t revents, 85 void* userData); 86 87 private: 88 /** 89 * @brief Update the present property for the inventory item. 90 * 91 * @param[in] present - What the present property should be set to. 92 */ 93 void updateInventory(bool present); 94 95 /** 96 * @brief Construct the inventory object map for the inventory item. 97 * 98 * @param[in] present - What the present property should be set to. 99 * 100 * @return The inventory object map to update inventory 101 */ 102 ObjectMap getObjectMap(bool present); 103 104 /** @brief Connection for sdbusplus bus */ 105 sdbusplus::bus::bus& bus; 106 107 /** 108 * @brief Read the GPIO device to determine initial presence and set 109 * present property at D-Bus path. 110 */ 111 void determinePresence(); 112 113 /** @brief Object path under inventory to display this inventory item */ 114 const std::string inventory; 115 116 /** @brief Pretty name of the inventory item*/ 117 const std::string name; 118 119 /** @brief Analyzes the GPIO event and update present property*/ 120 void analyzeEvent(); 121 122 /** @brief Vector of path and device tuples to bind/unbind*/ 123 const std::vector<Driver> drivers; 124 125 /** 126 * @brief Binds or unbinds drivers 127 * 128 * Called when a presence change is detected to either 129 * bind the drivers for the new card or unbind them for 130 * the just removed card. Operates on the drivers vector. 131 * 132 * Writes <device> to <path>/bind (or unbind) 133 * 134 * @param present - when true, will bind the drivers 135 * when false, will unbind them 136 */ 137 void bindOrUnbindDrivers(bool present); 138 }; 139 140 /** 141 * @brief Get the service name from the mapper for the 142 * interface and path passed in. 143 * 144 * @param[in] path - The D-Bus path name 145 * @param[in] interface - The D-Bus interface name 146 * @param[in] bus - The D-Bus bus object 147 * 148 * @return The service name 149 */ 150 std::string getService(const std::string& path, const std::string& interface, 151 sdbusplus::bus::bus& bus); 152 153 } // namespace presence 154 } // namespace gpio 155 } // namespace phosphor 156