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