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 * @param[in] isInventory - true if the callout path is an 78 * inventory path, false if it is a device path 79 */ Descriptor(const char * path,int err=0,const char * callout=nullptr,const bool isInventory=false)80 Descriptor(const char* path, int err = 0, const char* callout = nullptr, 81 const bool isInventory = false) : 82 log(true), err(err), callout(callout), path(path), 83 isInventoryCallout(isInventory) 84 {} 85 86 bool log; 87 int err; 88 const char* callout; 89 const char* path; 90 bool isInventoryCallout; 91 }; 92 93 /** @brief Starts to monitor for error conditions 94 * 95 * @param[in] poll - Indicates whether or not the error file should 96 * actually be polled for changes. Disabling polling is 97 * necessary for error files that don't support the poll 98 * file operation. 99 */ 100 void addWatch(bool poll = true); 101 102 /** @brief Removes error watch */ 103 void removeWatch(); 104 setFile(const fs::path & f)105 inline void setFile(const fs::path& f) 106 { 107 file = f; 108 } 109 110 private: 111 /** @brief sd_event wrapped in unique_ptr */ 112 EventPtr& event; 113 114 /** @brief event source wrapped in unique_ptr */ 115 EventSourcePtr eventSource; 116 117 /** @brief Current state of error watching */ 118 bool watching = false; 119 120 /** @brief attaches FD to events and sets up callback handler */ 121 void registerCallBack(); 122 123 /** @brief Opens the file and populates fd */ 124 void openFile(); 125 126 /** @brief Callback handler when the FD has some activity on it 127 * 128 * @param[in] es - Populated event source 129 * @param[in] fd - Associated File descriptor 130 * @param[in] revents - Type of event 131 * @param[in] userData - User data that was passed during registration 132 * 133 * @return - 0 or positive number on success and negative 134 * errno otherwise 135 */ 136 static int processEvents(sd_event_source* es, int fd, uint32_t revents, 137 void* userData); 138 139 /** @brief When the error event is received, analyzes it 140 * and makes a callback to error handler if the 141 * content denotes an error condition 142 */ 143 virtual void analyzeEvent(); 144 145 protected: 146 /** @brief File descriptor to watch for errors */ 147 int fd = -1; 148 149 /** Error file */ 150 fs::path file; 151 152 /** @brief Optional function to call on error scenario */ 153 std::function<void(int)> callBack; 154 155 /** @brief Reads file data 156 * 157 * @return data read. Since its a /sysfs entry, 158 * it would be a string 159 */ 160 std::string readFile(int) const; 161 }; 162 163 } // namespace occ 164 } // namespace open_power 165