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