1 #pragma once
2 
3 #include "utility.hpp"
4 
5 #include <nlohmann/json.hpp>
6 #include <xyz/openbmc_project/Logging/Entry/server.hpp>
7 
8 #include <filesystem>
9 #include <string>
10 #include <tuple>
11 
12 namespace phosphor::fan::monitor
13 {
14 
15 /**
16  * @class FFDCFile
17  *
18  * This class holds a file that is used for event log FFDC
19  * which needs a file descriptor as input.  The file is
20  * deleted upon destruction.
21  */
22 class FFDCFile
23 {
24   public:
25     FFDCFile() = delete;
26     FFDCFile(const FFDCFile&) = delete;
27     FFDCFile& operator=(const FFDCFile&) = delete;
28     FFDCFile(FFDCFile&&) = delete;
29     FFDCFile& operator=(FFDCFile&&) = delete;
30 
31     /**
32      * @brief Constructor
33      *
34      * Opens the file and saves the descriptor
35      *
36      * @param[in] name - The filename
37      */
38     explicit FFDCFile(const std::filesystem::path& name);
39 
40     /**
41      * @brief Destructor - Deletes the file
42      */
43     ~FFDCFile()
44     {
45         std::filesystem::remove(_name);
46     }
47 
48     /**
49      * @brief Returns the file descriptor
50      *
51      * @return int - The descriptor
52      */
53     int fd()
54     {
55         return _fd();
56     }
57 
58   private:
59     /**
60      * @brief The file descriptor holder
61      */
62     util::FileDescriptor _fd;
63 
64     /**
65      * @brief The filename
66      */
67     const std::filesystem::path _name;
68 };
69 
70 /**
71  * @class FanError
72  *
73  * This class represents a fan error.  It has a commit() interface
74  * that will create the event log with certain FFDC.
75  */
76 class FanError
77 {
78   public:
79     FanError() = delete;
80     ~FanError() = default;
81     FanError(const FanError&) = delete;
82     FanError& operator=(const FanError&) = delete;
83     FanError(FanError&&) = delete;
84     FanError& operator=(FanError&&) = delete;
85 
86     /**
87      * @brief Constructor
88      *
89      * @param[in] error - The error name, like
90      *                    xyz.openbmc_project.Fan.Error.Fault
91      * @param[in] fan - The failing fan's inventory path
92      * @param[in] sensor - The failing sensor's inventory path.  Can be empty
93      *                     if the error is for the FRU and not the sensor.
94      * @param[in] severity - The severity of the error
95      */
96     FanError(const std::string& error, const std::string& fan,
97              const std::string& sensor,
98              sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level
99                  severity) :
100         _errorName(error),
101         _fanName(fan), _sensorName(sensor),
102         _severity(
103             sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
104                 severity))
105     {}
106 
107     /**
108      * @brief Constructor
109      *
110      * This version doesn't take a fan or sensor name.
111      *
112      * @param[in] error - The error name, like
113      *                    xyz.openbmc_project.Fan.Error.Fault
114      * @param[in] severity - The severity of the error
115      */
116     FanError(const std::string& error,
117              sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level
118                  severity) :
119         _errorName(error),
120         _severity(
121             sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
122                 severity))
123     {}
124 
125     /**
126      * @brief Commits the error by calling the D-Bus method to create
127      *        the event log.
128      *
129      * The FFDC is passed in here so that if an error is committed
130      * more than once it can have up to date FFDC.
131      *
132      * @param[in] jsonFFDC - Free form JSON data that should be sent in as
133      *                       FFDC.
134      * @param[in] isPowerOffError - If this is committed at the time of the
135      *                              power off.
136      */
137     void commit(const nlohmann::json& jsonFFDC, bool isPowerOffError = false);
138 
139   private:
140     /**
141      * @brief Returns an FFDCFile holding the Logger contents
142      *
143      * @return std::unique_ptr<FFDCFile> - The file object
144      */
145     std::unique_ptr<FFDCFile> makeLogFFDCFile();
146 
147     /**
148      * @brief Returns an FFDCFile holding the contents of the JSON FFDC
149      *
150      * @param[in] ffdcData - The JSON data to write to a file
151      *
152      * @return std::unique_ptr<FFDCFile> - The file object
153      */
154     std::unique_ptr<FFDCFile> makeJsonFFDCFile(const nlohmann::json& ffdcData);
155 
156     /**
157      * @brief Create and returns the AdditionalData property to use for the
158      *        event log.
159      *
160      * @param[in] isPowerOffError - If this is committed at the time of the
161      *                              power off.
162      * @return map<string, string> - The AdditionalData contents
163      */
164     std::map<std::string, std::string> getAdditionalData(bool isPowerOffError);
165 
166     /**
167      * @brief The error name (The event log's 'Message' property)
168      */
169     const std::string _errorName;
170 
171     /**
172      * @brief The inventory name of the failing fan
173      */
174     const std::string _fanName;
175 
176     /**
177      * @brief The inventory name of the failing sensor, if there is one.
178      */
179     const std::string _sensorName;
180 
181     /**
182      * @brief The severity of the event log.  This is the string
183      *        representation of the Entry::Level property.
184      */
185     const std::string _severity;
186 };
187 
188 } // namespace phosphor::fan::monitor
189