1 #pragma once 2 3 #include "config.h" 4 5 #include "occ_events.hpp" 6 7 #include <unistd.h> 8 9 #include <filesystem> 10 #include <functional> 11 namespace open_power 12 { 13 namespace occ 14 { 15 16 namespace fs = std::filesystem; 17 18 constexpr auto PRESENCE_ERROR_PATH = 19 "org.open_power.OCC.Firmware.Error.PresenceMismatch"; 20 constexpr auto SAFE_ERROR_PATH = "org.open_power.OCC.Device.Error.SafeState"; 21 22 /** @class Error 23 * @brief Monitors for OCC device error condition 24 */ 25 class Error 26 { 27 public: 28 Error() = delete; 29 Error(const Error&) = delete; 30 Error& operator=(const Error&) = delete; 31 Error(Error&&) = default; 32 Error& operator=(Error&&) = default; 33 34 /** @brief Constructs the Error object 35 * 36 * @param[in] event - reference to sd_event unique_ptr 37 * @param[in] file - File used by driver to communicate errors 38 * @param[in] callBack - Optional function callback on error condition 39 */ 40 Error(EventPtr& event, const fs::path& file, 41 std::function<void(int)> callBack = nullptr) : 42 event(event), 43 file(file), callBack(callBack) 44 { 45 // Nothing to do here. 46 } 47 48 virtual ~Error() 49 { 50 if (fd >= 0) 51 { 52 close(fd); 53 } 54 } 55 56 /** @class Descriptor 57 * @brief Contains data relevant to an error that occurred. 58 */ 59 class Descriptor 60 { 61 public: 62 Descriptor(const Descriptor&) = default; 63 Descriptor& operator=(const Descriptor&) = default; 64 Descriptor(Descriptor&&) = default; 65 Descriptor& operator=(Descriptor&&) = default; 66 67 Descriptor() : log(false), err(0), callout(nullptr), path(nullptr) {} 68 69 /** @brief Constructs the Descriptor object 70 * 71 * @param[in] path - the DBus error path 72 * @param[in] err - Optional error return code 73 * @param[in] callout - Optional PEL callout path 74 */ 75 Descriptor(const char* path, int err = 0, 76 const char* callout = nullptr) : 77 log(true), 78 err(err), callout(callout), path(path) 79 {} 80 81 bool log; 82 int err; 83 const char* callout; 84 const char* path; 85 }; 86 87 /** @brief Starts to monitor for error conditions 88 * 89 * @param[in] poll - Indicates whether or not the error file should 90 * actually be polled for changes. Disabling polling is 91 * necessary for error files that don't support the poll 92 * file operation. 93 */ 94 void addWatch(bool poll = true); 95 96 /** @brief Removes error watch */ 97 void removeWatch(); 98 99 inline void setFile(const fs::path& f) 100 { 101 file = f; 102 } 103 104 private: 105 /** @brief sd_event wrapped in unique_ptr */ 106 EventPtr& event; 107 108 /** @brief event source wrapped in unique_ptr */ 109 EventSourcePtr eventSource; 110 111 /** @brief Current state of error watching */ 112 bool watching = false; 113 114 /** @brief attaches FD to events and sets up callback handler */ 115 void registerCallBack(); 116 117 /** @brief Opens the file and populates fd */ 118 void openFile(); 119 120 /** @brief Callback handler when the FD has some activity on it 121 * 122 * @param[in] es - Populated event source 123 * @param[in] fd - Associated File descriptor 124 * @param[in] revents - Type of event 125 * @param[in] userData - User data that was passed during registration 126 * 127 * @return - 0 or positive number on success and negative 128 * errno otherwise 129 */ 130 static int processEvents(sd_event_source* es, int fd, uint32_t revents, 131 void* userData); 132 133 /** @brief When the error event is received, analyzes it 134 * and makes a callback to error handler if the 135 * content denotes an error condition 136 */ 137 virtual void analyzeEvent(); 138 139 protected: 140 /** @brief File descriptor to watch for errors */ 141 int fd = -1; 142 143 /** Error file */ 144 fs::path file; 145 146 /** @brief Optional function to call on error scenario */ 147 std::function<void(int)> callBack; 148 149 /** @brief Reads file data 150 * 151 * @return data read. Since its a /sysfs entry, 152 * it would be a string 153 */ 154 std::string readFile(int) const; 155 }; 156 157 } // namespace occ 158 } // namespace open_power 159