blob: b5feddd6a7173b09e958620a508a6afdd21b1ea8 [file] [log] [blame]
Gunnar Mills72639152017-06-22 15:06:21 -05001#pragma once
Matt Spinler902d1c32017-09-01 11:03:02 -05002#include <experimental/filesystem>
Gunnar Mills5f101102017-06-29 13:07:39 -05003#include <string>
Gunnar Mills765725e2017-07-06 14:17:44 -05004#include <systemd/sd-event.h>
Gunnar Mills835dfb82017-07-26 16:15:21 -05005#include "evdev.hpp"
Gunnar Mills72639152017-06-22 15:06:21 -05006
7namespace phosphor
8{
9namespace gpio
10{
11namespace presence
12{
13
Matt Spinler902d1c32017-09-01 11:03:02 -050014static constexpr auto deviceField = 0;
15static constexpr auto pathField = 1;
16using Device = std::string;
17using Path = std::experimental::filesystem::path;
18using Driver = std::tuple<Device, Path>;
19
Gunnar Mills5f101102017-06-29 13:07:39 -050020/** @class Presence
Gunnar Mills835dfb82017-07-26 16:15:21 -050021 * @brief Responsible for determining and monitoring presence,
22 * by monitoring GPIO state changes, of inventory items and
23 * updating D-Bus accordingly.
Gunnar Mills5f101102017-06-29 13:07:39 -050024 */
Gunnar Mills835dfb82017-07-26 16:15:21 -050025class Presence : public Evdev
Gunnar Mills5f101102017-06-29 13:07:39 -050026{
27
Gunnar Mills80292bb2017-07-05 16:34:51 -050028 using Property = std::string;
29 using Value = sdbusplus::message::variant<bool, std::string>;
30 // Association between property and its value
31 using PropertyMap = std::map<Property, Value>;
32 using Interface = std::string;
33 // Association between interface and the D-Bus property
34 using InterfaceMap = std::map<Interface, PropertyMap>;
35 using Object = sdbusplus::message::object_path;
36 // Association between object and the interface
37 using ObjectMap = std::map<Object, InterfaceMap>;
38
Gunnar Mills5f101102017-06-29 13:07:39 -050039 public:
40 Presence() = delete;
41 ~Presence() = default;
42 Presence(const Presence&) = delete;
43 Presence& operator=(const Presence&) = delete;
44 Presence(Presence&&) = delete;
45 Presence& operator=(Presence&&) = delete;
46
47 /** @brief Constructs Presence object.
48 *
Gunnar Mills80292bb2017-07-05 16:34:51 -050049 * @param[in] bus - D-Bus bus Object
Gunnar Mills5f101102017-06-29 13:07:39 -050050 * @param[in] inventory - Object path under inventory
51 to display this inventory item
52 * @param[in] path - Device path to read for GPIO pin state
53 to determine presence of inventory item
54 * @param[in] key - GPIO key to monitor
55 * @param[in] name - Pretty name of the inventory item
Gunnar Mills765725e2017-07-06 14:17:44 -050056 * @param[in] event - sd_event handler
Matt Spinler902d1c32017-09-01 11:03:02 -050057 * @param[in] drivers - list of device drivers to bind and unbind
Gunnar Mills765725e2017-07-06 14:17:44 -050058 * @param[in] handler - IO callback handler. Defaults to one in this
59 * class
Gunnar Mills5f101102017-06-29 13:07:39 -050060 */
Gunnar Mills80292bb2017-07-05 16:34:51 -050061 Presence(sdbusplus::bus::bus& bus,
62 const std::string& inventory,
Gunnar Mills5f101102017-06-29 13:07:39 -050063 const std::string& path,
64 const unsigned int key,
Gunnar Mills765725e2017-07-06 14:17:44 -050065 const std::string& name,
66 EventPtr& event,
Matt Spinler902d1c32017-09-01 11:03:02 -050067 const std::vector<Driver>& drivers,
Gunnar Mills765725e2017-07-06 14:17:44 -050068 sd_event_io_handler_t handler = Presence::processEvents) :
Gunnar Mills835dfb82017-07-26 16:15:21 -050069 Evdev(path, key, event, handler, true),
Gunnar Mills80292bb2017-07-05 16:34:51 -050070 bus(bus),
Gunnar Mills5f101102017-06-29 13:07:39 -050071 inventory(inventory),
Matt Spinler902d1c32017-09-01 11:03:02 -050072 name(name),
73 drivers(drivers)
Gunnar Mills5f101102017-06-29 13:07:39 -050074 {
Gunnar Mills5f101102017-06-29 13:07:39 -050075 determinePresence();
76 }
77
Gunnar Mills765725e2017-07-06 14:17:44 -050078 /** @brief Callback handler when the FD has some activity on it
79 *
80 * @param[in] es - Populated event source
81 * @param[in] fd - Associated File descriptor
82 * @param[in] revents - Type of event
83 * @param[in] userData - User data that was passed during registration
84 *
85 * @return - 0 or positive number on success and negative
86 * errno otherwise
87 */
88 static int processEvents(sd_event_source* es, int fd,
89 uint32_t revents, void* userData);
90
Gunnar Mills5f101102017-06-29 13:07:39 -050091 private:
92 /**
Gunnar Mills80292bb2017-07-05 16:34:51 -050093 * @brief Update the present property for the inventory item.
94 *
95 * @param[in] present - What the present property should be set to.
96 */
97 void updateInventory(bool present);
98
99 /**
100 * @brief Construct the inventory object map for the inventory item.
101 *
102 * @param[in] present - What the present property should be set to.
103 *
104 * @return The inventory object map to update inventory
105 */
106 ObjectMap getObjectMap(bool present);
107
108 /** @brief Connection for sdbusplus bus */
109 sdbusplus::bus::bus& bus;
110
111 /**
Gunnar Mills5f101102017-06-29 13:07:39 -0500112 * @brief Read the GPIO device to determine initial presence and set
113 * present property at D-Bus path.
Matt Spinler902d1c32017-09-01 11:03:02 -0500114 */
Gunnar Mills5f101102017-06-29 13:07:39 -0500115 void determinePresence();
116
117 /** @brief Object path under inventory to display this inventory item */
118 const std::string inventory;
119
Gunnar Mills5f101102017-06-29 13:07:39 -0500120 /** @brief Pretty name of the inventory item*/
121 const std::string name;
122
Gunnar Mills765725e2017-07-06 14:17:44 -0500123 /** @brief Analyzes the GPIO event and update present property*/
124 void analyzeEvent();
Matt Spinler902d1c32017-09-01 11:03:02 -0500125
126 /** @brief Vector of path and device tuples to bind/unbind*/
127 const std::vector<Driver> drivers;
128
129 /**
130 * @brief Binds or unbinds drivers
131 *
132 * Called when a presence change is detected to either
133 * bind the drivers for the new card or unbind them for
134 * the just removed card. Operates on the drivers vector.
135 *
136 * Writes <device> to <path>/bind (or unbind)
137 *
138 * @param present - when true, will bind the drivers
139 * when false, will unbind them
140 */
141 void bindOrUnbindDrivers(bool present);
Gunnar Mills5f101102017-06-29 13:07:39 -0500142};
143
Gunnar Mills80292bb2017-07-05 16:34:51 -0500144/**
145 * @brief Get the service name from the mapper for the
146 * interface and path passed in.
147 *
148 * @param[in] path - The D-Bus path name
149 * @param[in] interface - The D-Bus interface name
150 * @param[in] bus - The D-Bus bus object
151 *
152 * @return The service name
153 */
154std::string getService(const std::string& path,
155 const std::string& interface,
156 sdbusplus::bus::bus& bus);
157
Gunnar Mills72639152017-06-22 15:06:21 -0500158} // namespace presence
159} // namespace gpio
160} // namespace phosphor
161