1ee4d83dfSVishwanatha Subbanna #pragma once
2ee4d83dfSVishwanatha Subbanna 
3ee4d83dfSVishwanatha Subbanna #include "config.h"
494df8c90SGunnar Mills 
594df8c90SGunnar Mills #include "occ_events.hpp"
694df8c90SGunnar Mills 
794df8c90SGunnar Mills #include <unistd.h>
894df8c90SGunnar Mills 
9bcef3b48SGeorge Liu #include <filesystem>
1094df8c90SGunnar Mills #include <functional>
11ee4d83dfSVishwanatha Subbanna namespace open_power
12ee4d83dfSVishwanatha Subbanna {
13ee4d83dfSVishwanatha Subbanna namespace occ
14ee4d83dfSVishwanatha Subbanna {
15ee4d83dfSVishwanatha Subbanna 
16bcef3b48SGeorge Liu namespace fs = std::filesystem;
17ee4d83dfSVishwanatha Subbanna 
189789e71fSEddie James constexpr auto PRESENCE_ERROR_PATH =
19fec4b0b1SMatt Spinler     "org.open_power.OCC.Firmware.Error.PresenceMismatch";
20fec4b0b1SMatt Spinler constexpr auto SAFE_ERROR_PATH = "org.open_power.OCC.Device.Error.SafeState";
21*4b82f3e3SChris Cain constexpr auto MISSING_OCC_SENSORS_PATH =
22*4b82f3e3SChris Cain     "org.open_power.OCC.Firmware.Error.MissingOCCSensors";
239789e71fSEddie James 
24ee4d83dfSVishwanatha Subbanna /** @class Error
25ee4d83dfSVishwanatha Subbanna  *  @brief Monitors for OCC device error condition
26ee4d83dfSVishwanatha Subbanna  */
27ee4d83dfSVishwanatha Subbanna class Error
28ee4d83dfSVishwanatha Subbanna {
29ee4d83dfSVishwanatha Subbanna   public:
30ee4d83dfSVishwanatha Subbanna     Error() = delete;
31ee4d83dfSVishwanatha Subbanna     Error(const Error&) = delete;
32ee4d83dfSVishwanatha Subbanna     Error& operator=(const Error&) = delete;
33ee4d83dfSVishwanatha Subbanna     Error(Error&&) = default;
34ee4d83dfSVishwanatha Subbanna     Error& operator=(Error&&) = default;
35ee4d83dfSVishwanatha Subbanna 
36ee4d83dfSVishwanatha Subbanna     /** @brief Constructs the Error object
37ee4d83dfSVishwanatha Subbanna      *
38ee4d83dfSVishwanatha Subbanna      *  @param[in] event    - reference to sd_event unique_ptr
39ee4d83dfSVishwanatha Subbanna      *  @param[in] file     - File used by driver to communicate errors
40ee4d83dfSVishwanatha Subbanna      *  @param[in] callBack - Optional function callback on error condition
41ee4d83dfSVishwanatha Subbanna      */
Error(EventPtr & event,const fs::path & file,std::function<void (int)> callBack=nullptr)4294df8c90SGunnar Mills     Error(EventPtr& event, const fs::path& file,
439789e71fSEddie James           std::function<void(int)> callBack = nullptr) :
44ee4d83dfSVishwanatha Subbanna         event(event),
45774f9af9SEddie James         file(file), callBack(callBack)
46ee4d83dfSVishwanatha Subbanna     {
47ee4d83dfSVishwanatha Subbanna         // Nothing to do here.
48ee4d83dfSVishwanatha Subbanna     }
49ee4d83dfSVishwanatha Subbanna 
~Error()50bddcf853SGeorge Liu     virtual ~Error()
51ee4d83dfSVishwanatha Subbanna     {
52ee4d83dfSVishwanatha Subbanna         if (fd >= 0)
53ee4d83dfSVishwanatha Subbanna         {
54ee4d83dfSVishwanatha Subbanna             close(fd);
55ee4d83dfSVishwanatha Subbanna         }
56ee4d83dfSVishwanatha Subbanna     }
57ee4d83dfSVishwanatha Subbanna 
589789e71fSEddie James     /** @class Descriptor
599789e71fSEddie James      *  @brief Contains data relevant to an error that occurred.
609789e71fSEddie James      */
619789e71fSEddie James     class Descriptor
629789e71fSEddie James     {
639789e71fSEddie James       public:
649789e71fSEddie James         Descriptor(const Descriptor&) = default;
659789e71fSEddie James         Descriptor& operator=(const Descriptor&) = default;
669789e71fSEddie James         Descriptor(Descriptor&&) = default;
679789e71fSEddie James         Descriptor& operator=(Descriptor&&) = default;
689789e71fSEddie James 
Descriptor()69a49c987eSPatrick Williams         Descriptor() : log(false), err(0), callout(nullptr), path(nullptr) {}
709789e71fSEddie James 
719789e71fSEddie James         /** @brief Constructs the Descriptor object
729789e71fSEddie James          *
739789e71fSEddie James          *  @param[in] path - the DBus error path
749789e71fSEddie James          *  @param[in] err - Optional error return code
759789e71fSEddie James          *  @param[in] callout - Optional PEL callout path
769789e71fSEddie James          */
Descriptor(const char * path,int err=0,const char * callout=nullptr)779789e71fSEddie James         Descriptor(const char* path, int err = 0,
789789e71fSEddie James                    const char* callout = nullptr) :
799789e71fSEddie James             log(true),
809789e71fSEddie James             err(err), callout(callout), path(path)
819789e71fSEddie James         {}
829789e71fSEddie James 
839789e71fSEddie James         bool log;
849789e71fSEddie James         int err;
859789e71fSEddie James         const char* callout;
869789e71fSEddie James         const char* path;
879789e71fSEddie James     };
889789e71fSEddie James 
89774f9af9SEddie James     /** @brief Starts to monitor for error conditions
90774f9af9SEddie James      *
91774f9af9SEddie James      *  @param[in] poll - Indicates whether or not the error file should
92774f9af9SEddie James      *                    actually be polled for changes. Disabling polling is
93774f9af9SEddie James      *                    necessary for error files that don't support the poll
94774f9af9SEddie James      *                    file operation.
95774f9af9SEddie James      */
96774f9af9SEddie James     void addWatch(bool poll = true);
97ee4d83dfSVishwanatha Subbanna 
98ee4d83dfSVishwanatha Subbanna     /** @brief Removes error watch */
99ee4d83dfSVishwanatha Subbanna     void removeWatch();
100ee4d83dfSVishwanatha Subbanna 
setFile(const fs::path & f)101774f9af9SEddie James     inline void setFile(const fs::path& f)
102774f9af9SEddie James     {
103774f9af9SEddie James         file = f;
104774f9af9SEddie James     }
105774f9af9SEddie James 
106ee4d83dfSVishwanatha Subbanna   private:
107ee4d83dfSVishwanatha Subbanna     /** @brief sd_event wrapped in unique_ptr */
108ee4d83dfSVishwanatha Subbanna     EventPtr& event;
109ee4d83dfSVishwanatha Subbanna 
110ee4d83dfSVishwanatha Subbanna     /** @brief event source wrapped in unique_ptr */
111ee4d83dfSVishwanatha Subbanna     EventSourcePtr eventSource;
112ee4d83dfSVishwanatha Subbanna 
1132dc9b1a2SVishwanatha Subbanna     /** @brief Current state of error watching */
1142dc9b1a2SVishwanatha Subbanna     bool watching = false;
1152dc9b1a2SVishwanatha Subbanna 
116ee4d83dfSVishwanatha Subbanna     /** @brief attaches FD to events and sets up callback handler */
117ee4d83dfSVishwanatha Subbanna     void registerCallBack();
118ee4d83dfSVishwanatha Subbanna 
119ee4d83dfSVishwanatha Subbanna     /** @brief Opens the file and populates fd */
120ee4d83dfSVishwanatha Subbanna     void openFile();
121ee4d83dfSVishwanatha Subbanna 
122ee4d83dfSVishwanatha Subbanna     /** @brief Callback handler when the FD has some activity on it
123ee4d83dfSVishwanatha Subbanna      *
124ee4d83dfSVishwanatha Subbanna      *  @param[in] es       - Populated event source
125ee4d83dfSVishwanatha Subbanna      *  @param[in] fd       - Associated File descriptor
126ee4d83dfSVishwanatha Subbanna      *  @param[in] revents  - Type of event
127ee4d83dfSVishwanatha Subbanna      *  @param[in] userData - User data that was passed during registration
128ee4d83dfSVishwanatha Subbanna      *
129ee4d83dfSVishwanatha Subbanna      *  @return             - 0 or positive number on success and negative
130ee4d83dfSVishwanatha Subbanna      *                        errno otherwise
131ee4d83dfSVishwanatha Subbanna      */
13294df8c90SGunnar Mills     static int processEvents(sd_event_source* es, int fd, uint32_t revents,
13394df8c90SGunnar Mills                              void* userData);
134ee4d83dfSVishwanatha Subbanna 
135ee4d83dfSVishwanatha Subbanna     /** @brief When the error event is received, analyzes it
136ee4d83dfSVishwanatha Subbanna      *         and makes a callback to error handler if the
137ee4d83dfSVishwanatha Subbanna      *         content denotes an error condition
138ee4d83dfSVishwanatha Subbanna      */
139636577f4SEdward A. James     virtual void analyzeEvent();
140636577f4SEdward A. James 
141636577f4SEdward A. James   protected:
142636577f4SEdward A. James     /** @brief File descriptor to watch for errors */
143636577f4SEdward A. James     int fd = -1;
144636577f4SEdward A. James 
145636577f4SEdward A. James     /** Error file */
146774f9af9SEddie James     fs::path file;
147636577f4SEdward A. James 
148636577f4SEdward A. James     /** @brief Optional function to call on error scenario */
1499789e71fSEddie James     std::function<void(int)> callBack;
150636577f4SEdward A. James 
151636577f4SEdward A. James     /** @brief Reads file data
152636577f4SEdward A. James      *
153636577f4SEdward A. James      *  @return data read. Since its a /sysfs entry,
154636577f4SEdward A. James      *          it would be a string
155636577f4SEdward A. James      */
156636577f4SEdward A. James     std::string readFile(int) const;
157ee4d83dfSVishwanatha Subbanna };
158ee4d83dfSVishwanatha Subbanna 
159ee4d83dfSVishwanatha Subbanna } // namespace occ
160ee4d83dfSVishwanatha Subbanna } // namespace open_power
161