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