1 #pragma once
2 
3 #include <unistd.h>
4 #include <functional>
5 #include <experimental/filesystem>
6 #include "occ_events.hpp"
7 #include "config.h"
8 namespace open_power
9 {
10 namespace occ
11 {
12 
13 namespace fs = std::experimental::filesystem;
14 
15 /** @class Error
16  *  @brief Monitors for OCC device error condition
17  */
18 class Error
19 {
20     public:
21         Error() = delete;
22         Error(const Error&) = delete;
23         Error& operator=(const Error&) = delete;
24         Error(Error&&) = default;
25         Error& operator=(Error&&) = default;
26 
27         /** @brief Constructs the Error object
28          *
29          *  @param[in] event    - reference to sd_event unique_ptr
30          *  @param[in] file     - File used by driver to communicate errors
31          *  @param[in] callBack - Optional function callback on error condition
32          */
33         Error(EventPtr& event,
34               const fs::path& file,
35               std::function<void()> callBack = nullptr) :
36             event(event),
37             file(fs::path(DEV_PATH) / file),
38             callBack(callBack)
39         {
40             // Nothing to do here.
41         }
42 
43         ~Error()
44         {
45             if (fd>= 0)
46             {
47                 close(fd);
48             }
49         }
50 
51         /** @brief Starts to monitor for error conditions */
52         void addWatch();
53 
54         /** @brief Removes error watch */
55         void removeWatch();
56 
57     private:
58         /** @brief sd_event wrapped in unique_ptr */
59         EventPtr& event;
60 
61         /** @brief event source wrapped in unique_ptr */
62         EventSourcePtr eventSource;
63 
64         /** Error file */
65         const fs::path file;
66 
67         /** @brief Optional function to call on error scenario */
68         std::function<void()> callBack;
69 
70         /** @brief File descriptor to watch for errors */
71         int fd = -1;
72 
73         /** @brief attaches FD to events and sets up callback handler */
74         void registerCallBack();
75 
76         /** @brief Opens the file and populates fd */
77         void openFile();
78 
79         /** @brief Reads file data
80          *
81          *  @return data read. Since its a /sysfs entry,
82          *          it would be a string
83          */
84         std::string readFile(int) const;
85 
86         /** @brief Callback handler when the FD has some activity on it
87          *
88          *  @param[in] es       - Populated event source
89          *  @param[in] fd       - Associated File descriptor
90          *  @param[in] revents  - Type of event
91          *  @param[in] userData - User data that was passed during registration
92          *
93          *  @return             - 0 or positive number on success and negative
94          *                        errno otherwise
95          */
96         static int processEvents(sd_event_source* es, int fd,
97                                  uint32_t revents, void* userData);
98 
99         /** @brief When the error event is received, analyzes it
100          *         and makes a callback to error handler if the
101          *         content denotes an error condition
102          */
103         void analyzeEvent();
104 };
105 
106 } // namespace occ
107 } // namespace open_power
108