| #pragma once |
| |
| #include "config.h" |
| |
| #include "occ_events.hpp" |
| |
| #include <unistd.h> |
| |
| #include <filesystem> |
| #include <functional> |
| namespace open_power |
| { |
| namespace occ |
| { |
| |
| namespace fs = std::filesystem; |
| |
| constexpr auto PRESENCE_ERROR_PATH = |
| "org.open_power.OCC.Firmware.Error.PresenceMismatch"; |
| constexpr auto SAFE_ERROR_PATH = "org.open_power.OCC.Device.Error.SafeState"; |
| |
| /** @class Error |
| * @brief Monitors for OCC device error condition |
| */ |
| class Error |
| { |
| public: |
| Error() = delete; |
| Error(const Error&) = delete; |
| Error& operator=(const Error&) = delete; |
| Error(Error&&) = default; |
| Error& operator=(Error&&) = default; |
| |
| /** @brief Constructs the Error object |
| * |
| * @param[in] event - reference to sd_event unique_ptr |
| * @param[in] file - File used by driver to communicate errors |
| * @param[in] callBack - Optional function callback on error condition |
| */ |
| Error(EventPtr& event, const fs::path& file, |
| std::function<void(int)> callBack = nullptr) : |
| event(event), |
| file(file), callBack(callBack) |
| { |
| // Nothing to do here. |
| } |
| |
| virtual ~Error() |
| { |
| if (fd >= 0) |
| { |
| close(fd); |
| } |
| } |
| |
| /** @class Descriptor |
| * @brief Contains data relevant to an error that occurred. |
| */ |
| class Descriptor |
| { |
| public: |
| Descriptor(const Descriptor&) = default; |
| Descriptor& operator=(const Descriptor&) = default; |
| Descriptor(Descriptor&&) = default; |
| Descriptor& operator=(Descriptor&&) = default; |
| |
| Descriptor() : log(false), err(0), callout(nullptr), path(nullptr) {} |
| |
| /** @brief Constructs the Descriptor object |
| * |
| * @param[in] path - the DBus error path |
| * @param[in] err - Optional error return code |
| * @param[in] callout - Optional PEL callout path |
| */ |
| Descriptor(const char* path, int err = 0, |
| const char* callout = nullptr) : |
| log(true), |
| err(err), callout(callout), path(path) |
| {} |
| |
| bool log; |
| int err; |
| const char* callout; |
| const char* path; |
| }; |
| |
| /** @brief Starts to monitor for error conditions |
| * |
| * @param[in] poll - Indicates whether or not the error file should |
| * actually be polled for changes. Disabling polling is |
| * necessary for error files that don't support the poll |
| * file operation. |
| */ |
| void addWatch(bool poll = true); |
| |
| /** @brief Removes error watch */ |
| void removeWatch(); |
| |
| inline void setFile(const fs::path& f) |
| { |
| file = f; |
| } |
| |
| private: |
| /** @brief sd_event wrapped in unique_ptr */ |
| EventPtr& event; |
| |
| /** @brief event source wrapped in unique_ptr */ |
| EventSourcePtr eventSource; |
| |
| /** @brief Current state of error watching */ |
| bool watching = false; |
| |
| /** @brief attaches FD to events and sets up callback handler */ |
| void registerCallBack(); |
| |
| /** @brief Opens the file and populates fd */ |
| void openFile(); |
| |
| /** @brief Callback handler when the FD has some activity on it |
| * |
| * @param[in] es - Populated event source |
| * @param[in] fd - Associated File descriptor |
| * @param[in] revents - Type of event |
| * @param[in] userData - User data that was passed during registration |
| * |
| * @return - 0 or positive number on success and negative |
| * errno otherwise |
| */ |
| static int processEvents(sd_event_source* es, int fd, uint32_t revents, |
| void* userData); |
| |
| /** @brief When the error event is received, analyzes it |
| * and makes a callback to error handler if the |
| * content denotes an error condition |
| */ |
| virtual void analyzeEvent(); |
| |
| protected: |
| /** @brief File descriptor to watch for errors */ |
| int fd = -1; |
| |
| /** Error file */ |
| fs::path file; |
| |
| /** @brief Optional function to call on error scenario */ |
| std::function<void(int)> callBack; |
| |
| /** @brief Reads file data |
| * |
| * @return data read. Since its a /sysfs entry, |
| * it would be a string |
| */ |
| std::string readFile(int) const; |
| }; |
| |
| } // namespace occ |
| } // namespace open_power |