xref: /openbmc/openpower-occ-control/occ_errors.hpp (revision 3ece5b99026970e1cf9bc7e797aff4c1be81b2f3)
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