blob: eb2f470a23f84e57f581b7649c9b28904523d967 [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#include "event_logger.hpp"
2
3#include "logger.hpp"
4
5#include <systemd/sd-bus.h>
6
7namespace vpd
8{
9const std::unordered_map<types::SeverityType, std::string>
10 EventLogger::m_severityMap = {
11 {types::SeverityType::Notice,
12 "xyz.openbmc_project.Logging.Entry.Level.Notice"},
13 {types::SeverityType::Informational,
14 "xyz.openbmc_project.Logging.Entry.Level.Informational"},
15 {types::SeverityType::Debug,
16 "xyz.openbmc_project.Logging.Entry.Level.Debug"},
17 {types::SeverityType::Warning,
18 "xyz.openbmc_project.Logging.Entry.Level.Warning"},
19 {types::SeverityType::Critical,
20 "xyz.openbmc_project.Logging.Entry.Level.Critical"},
21 {types::SeverityType::Emergency,
22 "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
23 {types::SeverityType::Alert,
24 "xyz.openbmc_project.Logging.Entry.Level.Alert"},
25 {types::SeverityType::Error,
26 "xyz.openbmc_project.Logging.Entry.Level.Error"}};
27
28const std::unordered_map<types::ErrorType, std::string>
29 EventLogger::m_errorMsgMap = {
30 {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
31 {types::ErrorType::InvalidVpdMessage, "com.ibm.VPD.Error.InvalidVPD"},
32 {types::ErrorType::VpdMismatch, "com.ibm.VPD.Error.Mismatch"},
33 {types::ErrorType::InvalidEeprom,
34 "com.ibm.VPD.Error.InvalidEepromPath"},
35 {types::ErrorType::EccCheckFailed, "com.ibm.VPD.Error.EccCheckFailed"},
36 {types::ErrorType::JsonFailure, "com.ibm.VPD.Error.InvalidJson"},
37 {types::ErrorType::DbusFailure, "com.ibm.VPD.Error.DbusFailure"},
38 {types::ErrorType::InvalidSystem,
39 "com.ibm.VPD.Error.UnknownSystemType"},
40 {types::ErrorType::EssentialFru,
41 "com.ibm.VPD.Error.RequiredFRUMissing"},
Sunny Srivastavaa88a2982025-01-23 12:03:21 +053042 {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"},
43 {types::ErrorType::InternalFailure,
44 "xyz.openbmc_project.Common.Error.InternalFailure"},
45 {types::ErrorType::FruMissing, "com.ibm.VPD.Error.RequiredFRUMissing"}};
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050046
47const std::unordered_map<types::CalloutPriority, std::string>
48 EventLogger::m_priorityMap = {
49 {types::CalloutPriority::High, "H"},
50 {types::CalloutPriority::Medium, "M"},
51 {types::CalloutPriority::MediumGroupA, "A"},
52 {types::CalloutPriority::MediumGroupB, "B"},
53 {types::CalloutPriority::MediumGroupC, "C"},
54 {types::CalloutPriority::Low, "L"}};
55
56void EventLogger::createAsyncPelWithInventoryCallout(
57 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
58 const std::vector<types::InventoryCalloutData>& i_callouts,
59 const std::string& i_fileName, const std::string& i_funcName,
60 const uint8_t i_internalRc, const std::string& i_description,
61 const std::optional<std::string> i_userData1,
62 const std::optional<std::string> i_userData2,
63 const std::optional<std::string> i_symFru,
64 const std::optional<std::string> i_procedure)
65{
66 (void)i_symFru;
67 (void)i_procedure;
68
69 try
70 {
71 if (i_callouts.empty())
72 {
73 logging::logMessage("Callout information is missing to create PEL");
74 // TODO: Revisit this instead of simpley returning.
75 return;
76 }
77
78 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
79 {
80 throw std::runtime_error(
81 "Error type not found in the error message map to create PEL");
82 // TODO: Need to handle, instead of throwing exception. Create
83 // default message in message_registry.json.
84 }
85
86 const std::string& l_message = m_errorMsgMap.at(i_errorType);
87
88 const std::string& l_severity =
89 (m_severityMap.find(i_severity) != m_severityMap.end()
90 ? m_severityMap.at(i_severity)
91 : m_severityMap.at(types::SeverityType::Informational));
92
93 std::string l_description =
94 (!i_description.empty() ? i_description : "VPD generic error");
95
96 std::string l_userData1 = (i_userData1) ? (*i_userData1) : "";
97
98 std::string l_userData2 = (i_userData2) ? (*i_userData2) : "";
99
100 const types::InventoryCalloutData& l_invCallout = i_callouts[0];
101 // TODO: Need to handle multiple inventory path callout's, when multiple
102 // callout's is supported by "Logging" service.
103
104 const types::CalloutPriority& l_priorityEnum = get<1>(l_invCallout);
105
106 const std::string& l_priority =
107 (m_priorityMap.find(l_priorityEnum) != m_priorityMap.end()
108 ? m_priorityMap.at(l_priorityEnum)
109 : m_priorityMap.at(types::CalloutPriority::Low));
110
111 sd_bus* l_sdBus = nullptr;
112 sd_bus_default(&l_sdBus);
113
114 const uint8_t l_additionalDataCount = 8;
115 auto l_rc = sd_bus_call_method_async(
116 l_sdBus, NULL, constants::eventLoggingServiceName,
117 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
118 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
119 l_severity.c_str(), l_additionalDataCount, "FileName",
120 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
121 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
122 l_description.c_str(), "UserData1", l_userData1.c_str(),
123 "UserData2", l_userData2.c_str(), "CALLOUT_INVENTORY_PATH",
124 get<0>(l_invCallout).c_str(), "CALLOUT_PRIORITY",
125 l_priority.c_str());
126
127 if (l_rc < 0)
128 {
129 logging::logMessage(
130 "Error calling sd_bus_call_method_async, Message = " +
131 std::string(strerror(-l_rc)));
132 }
133 }
134 catch (const std::exception& l_ex)
135 {
136 logging::logMessage(
137 "Create PEL failed with error: " + std::string(l_ex.what()));
138 }
139}
140
141void EventLogger::createAsyncPelWithI2cDeviceCallout(
142 const types::ErrorType i_errorType, const types::SeverityType i_severity,
143 const std::vector<types::DeviceCalloutData>& i_callouts,
144 const std::string& i_fileName, const std::string& i_funcName,
145 const uint8_t i_internalRc,
146 const std::optional<std::pair<std::string, std::string>> i_userData1,
147 const std::optional<std::pair<std::string, std::string>> i_userData2)
148{
149 // TODO, implementation needs to be added.
150 (void)i_errorType;
151 (void)i_severity;
152 (void)i_callouts;
153 (void)i_fileName;
154 (void)i_funcName;
155 (void)i_internalRc;
156 (void)i_userData1;
157 (void)i_userData2;
158}
159
160void EventLogger::createAsyncPelWithI2cBusCallout(
161 const types::ErrorType i_errorType, const types::SeverityType i_severity,
162 const std::vector<types::I2cBusCalloutData>& i_callouts,
163 const std::string& i_fileName, const std::string& i_funcName,
164 const uint8_t i_internalRc,
165 const std::optional<std::pair<std::string, std::string>> i_userData1,
166 const std::optional<std::pair<std::string, std::string>> i_userData2)
167{
168 // TODO, implementation needs to be added.
169 (void)i_errorType;
170 (void)i_severity;
171 (void)i_callouts;
172 (void)i_fileName;
173 (void)i_funcName;
174 (void)i_internalRc;
175 (void)i_userData1;
176 (void)i_userData2;
177}
178
179void EventLogger::createAsyncPel(
180 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
181 const std::string& i_fileName, const std::string& i_funcName,
182 const uint8_t i_internalRc, const std::string& i_description,
183 const std::optional<std::string> i_userData1,
184 const std::optional<std::string> i_userData2,
185 const std::optional<std::string> i_symFru,
186 const std::optional<std::string> i_procedure)
187{
188 (void)i_symFru;
189 (void)i_procedure;
190 try
191 {
192 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
193 {
194 throw std::runtime_error("Unsupported error type received");
195 // TODO: Need to handle, instead of throwing an exception.
196 }
197
198 const std::string& l_message = m_errorMsgMap.at(i_errorType);
199
200 const std::string& l_severity =
201 (m_severityMap.find(i_severity) != m_severityMap.end()
202 ? m_severityMap.at(i_severity)
203 : m_severityMap.at(types::SeverityType::Informational));
204
205 const std::string l_description =
206 ((!i_description.empty() ? i_description : "VPD generic error"));
207
208 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
209
210 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
211
212 sd_bus* l_sdBus = nullptr;
213 sd_bus_default(&l_sdBus);
214
215 // VALUE_6 represents the additional data pair count passing to create
216 // PEL. If there any change in additional data, we need to pass the
217 // correct number.
218 auto l_rc = sd_bus_call_method_async(
219 l_sdBus, NULL, constants::eventLoggingServiceName,
220 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
221 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
222 l_severity.c_str(), constants::VALUE_6, "FileName",
223 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
224 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
225 l_description.c_str(), "UserData1", l_userData1.c_str(),
226 "UserData2", l_userData2.c_str());
227
228 if (l_rc < 0)
229 {
230 logging::logMessage(
231 "Error calling sd_bus_call_method_async, Message = " +
232 std::string(strerror(-l_rc)));
233 }
234 }
235 catch (const sdbusplus::exception::SdBusError& l_ex)
236 {
237 logging::logMessage("Async PEL creation failed with an error: " +
238 std::string(l_ex.what()));
239 }
240}
241
242void EventLogger::createSyncPel(
243 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
244 const std::string& i_fileName, const std::string& i_funcName,
245 const uint8_t i_internalRc, const std::string& i_description,
246 const std::optional<std::string> i_userData1,
247 const std::optional<std::string> i_userData2,
248 const std::optional<std::string> i_symFru,
249 const std::optional<std::string> i_procedure)
250{
251 (void)i_symFru;
252 (void)i_procedure;
253 try
254 {
255 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
256 {
257 throw std::runtime_error("Unsupported error type received");
258 // TODO: Need to handle, instead of throwing an exception.
259 }
260
261 const std::string& l_message = m_errorMsgMap.at(i_errorType);
262
263 const std::string& l_severity =
264 (m_severityMap.find(i_severity) != m_severityMap.end()
265 ? m_severityMap.at(i_severity)
266 : m_severityMap.at(types::SeverityType::Informational));
267
268 const std::string l_description =
269 ((!i_description.empty() ? i_description : "VPD generic error"));
270
271 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
272
273 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
274
275 std::map<std::string, std::string> l_additionalData{
276 {"FileName", i_fileName},
277 {"FunctionName", i_funcName},
278 {"DESCRIPTION", l_description},
279 {"InteranlRc", std::to_string(i_internalRc)},
280 {"UserData1", l_userData1.c_str()},
281 {"UserData2", l_userData2.c_str()}};
282
283 auto l_bus = sdbusplus::bus::new_default();
284 auto l_method =
285 l_bus.new_method_call(constants::eventLoggingServiceName,
286 constants::eventLoggingObjectPath,
287 constants::eventLoggingInterface, "Create");
288 l_method.append(l_message, l_severity, l_additionalData);
289 l_bus.call(l_method);
290 }
291 catch (const sdbusplus::exception::SdBusError& l_ex)
292 {
293 logging::logMessage("Sync PEL creation failed with an error: " +
294 std::string(l_ex.what()));
295 }
296}
297} // namespace vpd