blob: 292842dcad8c94e4354a77158be532a798bbeeda [file] [log] [blame]
Patrick Venture3a5071a2018-09-12 13:27:42 -07001#include "storagehandler.hpp"
2
3#include "fruread.hpp"
4#include "read_fru_data.hpp"
5#include "selutility.hpp"
6#include "sensorhandler.hpp"
7#include "storageaddsel.hpp"
Patrick Venture3a5071a2018-09-12 13:27:42 -07008
Lei YU52d91242017-10-17 22:52:28 +08009#include <arpa/inet.h>
Patrick Venture3a5071a2018-09-12 13:27:42 -070010#include <mapper.h>
11#include <systemd/sd-bus.h>
Patrick Venture0b02be92018-08-31 11:55:55 -070012
13#include <algorithm>
Lei YU52d91242017-10-17 22:52:28 +080014#include <chrono>
15#include <cstdio>
Patrick Ventureb51bf9c2018-09-10 15:53:14 -070016#include <cstring>
Vernon Mauerybdda8002019-02-26 10:18:51 -080017#include <filesystem>
Vernon Mauerye08fbff2019-04-03 09:19:34 -070018#include <ipmid/api.hpp>
Vernon Mauery6a98fe72019-03-11 15:57:48 -070019#include <ipmid/utils.hpp>
Patrick Venture3a5071a2018-09-12 13:27:42 -070020#include <phosphor-logging/elog-errors.hpp>
21#include <phosphor-logging/log.hpp>
22#include <sdbusplus/server.hpp>
23#include <string>
Vernon Mauery16b86932019-05-01 08:36:11 -070024#include <variant>
Patrick Venture3a5071a2018-09-12 13:27:42 -070025#include <xyz/openbmc_project/Common/error.hpp>
26
Chris Austenb4f5b922015-10-13 12:44:43 -050027void register_netfn_storage_functions() __attribute__((constructor));
28
Patrick Venture0b02be92018-08-31 11:55:55 -070029unsigned int g_sel_time = 0xFFFFFFFF;
Patrick Venturedb0cbe62019-09-09 14:47:22 -070030namespace ipmi
31{
32namespace sensor
33{
34extern const IdInfoMap sensors;
35} // namespace sensor
36} // namespace ipmi
37
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -060038extern const FruMap frus;
anil kumar appana2c7db1d2019-05-28 11:20:19 +000039constexpr uint8_t eventDataSize = 3;
Patrick Venture0b02be92018-08-31 11:55:55 -070040namespace
41{
Lei YUe8939392017-06-15 10:45:05 +080042constexpr auto TIME_INTERFACE = "xyz.openbmc_project.Time.EpochTime";
George Liu4d623e92020-05-25 16:51:57 +080043constexpr auto BMC_TIME_PATH = "/xyz/openbmc_project/time/bmc";
Lei YUe8939392017-06-15 10:45:05 +080044constexpr auto DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
Patrick Venture0b02be92018-08-31 11:55:55 -070045constexpr auto PROPERTY_ELAPSED = "Elapsed";
Lei YUe8939392017-06-15 10:45:05 +080046
Lei YUd9555252021-09-14 20:30:41 +080047constexpr auto logWatchPath = "/xyz/openbmc_project/logging";
Lei YUd9e57662021-09-14 18:06:28 +080048constexpr auto logBasePath = "/xyz/openbmc_project/logging/entry";
49constexpr auto logEntryIntf = "xyz.openbmc_project.Logging.Entry";
50constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete";
Patrick Venture0b02be92018-08-31 11:55:55 -070051} // namespace
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +053052
Tom Joseph6f7deaa2017-06-30 19:03:54 +053053using InternalFailure =
Patrick Venture0b02be92018-08-31 11:55:55 -070054 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Tom Joseph6f7deaa2017-06-30 19:03:54 +053055using namespace phosphor::logging;
Marri Devender Raocac383b2017-07-03 13:24:27 -050056using namespace ipmi::fru;
57
Lei YUd9e57662021-09-14 18:06:28 +080058using SELRecordID = uint16_t;
59using SELEntry = ipmi::sel::SELEventRecordFormat;
60using SELCacheMap = std::map<SELRecordID, SELEntry>;
61
62SELCacheMap selCacheMap __attribute__((init_priority(101)));
Lei YU3df36612021-09-15 11:41:11 +080063bool selCacheMapInitialized;
Lei YUd9555252021-09-14 20:30:41 +080064std::unique_ptr<sdbusplus::bus::match::match> selAddedMatch
65 __attribute__((init_priority(101)));
Lei YUb6b72b02021-09-14 21:06:05 +080066std::unique_ptr<sdbusplus::bus::match::match> selRemovedMatch
67 __attribute__((init_priority(101)));
Lei YU4106e422021-09-15 10:55:51 +080068std::unique_ptr<sdbusplus::bus::match::match> selUpdatedMatch
69 __attribute__((init_priority(101)));
Lei YUd9e57662021-09-14 18:06:28 +080070
Lei YUb6b72b02021-09-14 21:06:05 +080071static inline uint16_t getLoggingId(const std::string& p)
Lei YUd9e57662021-09-14 18:06:28 +080072{
73 namespace fs = std::filesystem;
74 fs::path entryPath(p);
Lei YUb6b72b02021-09-14 21:06:05 +080075 return std::stoul(entryPath.filename().string());
76}
77
Lei YUeba8e9a2021-09-15 13:16:17 +080078static inline std::string getLoggingObjPath(uint16_t id)
79{
80 return std::string(ipmi::sel::logBasePath) + "/" + std::to_string(id);
81}
82
Lei YUb6b72b02021-09-14 21:06:05 +080083std::pair<uint16_t, SELEntry> parseLoggingEntry(const std::string& p)
84{
85 auto id = getLoggingId(p);
Lei YU3df36612021-09-15 11:41:11 +080086 ipmi::sel::GetSELEntryResponse record{};
87 try
88 {
89 record = ipmi::sel::convertLogEntrytoSEL(p);
90 }
91 catch (const std::exception& e)
92 {
93 fprintf(stderr, "Failed to convert %s to SEL: %s\n", p.c_str(),
94 e.what());
95 }
96 return {id, std::move(record.event)};
Lei YUd9e57662021-09-14 18:06:28 +080097}
98
Lei YUd9555252021-09-14 20:30:41 +080099static void selAddedCallback(sdbusplus::message::message& m)
100{
101 sdbusplus::message::object_path objPath;
102 try
103 {
104 m.read(objPath);
105 }
106 catch (const sdbusplus::exception::exception& e)
107 {
108 log<level::ERR>("Failed to read object path");
109 return;
110 }
111 std::string p = objPath;
112 selCacheMap.insert(parseLoggingEntry(p));
113}
114
Lei YUb6b72b02021-09-14 21:06:05 +0800115static void selRemovedCallback(sdbusplus::message::message& m)
116{
117 sdbusplus::message::object_path objPath;
118 try
119 {
120 m.read(objPath);
121 }
122 catch (const sdbusplus::exception::exception& e)
123 {
124 log<level::ERR>("Failed to read object path");
125 return;
126 }
127 std::string p = objPath;
128 selCacheMap.erase(getLoggingId(p));
129}
130
Lei YU4106e422021-09-15 10:55:51 +0800131static void selUpdatedCallback(sdbusplus::message::message& m)
132{
133 std::string p = m.get_path();
134 auto entry = parseLoggingEntry(p);
135 selCacheMap.insert_or_assign(entry.first, std::move(entry.second));
136}
137
Lei YUd9555252021-09-14 20:30:41 +0800138void registerSelCallbackHandler()
139{
140 using namespace sdbusplus::bus::match::rules;
141 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
142 if (!selAddedMatch)
143 {
144 selAddedMatch = std::make_unique<sdbusplus::bus::match::match>(
145 bus, interfacesAdded(logWatchPath),
146 std::bind(selAddedCallback, std::placeholders::_1));
147 }
Lei YUb6b72b02021-09-14 21:06:05 +0800148 if (!selRemovedMatch)
149 {
150 selRemovedMatch = std::make_unique<sdbusplus::bus::match::match>(
151 bus, interfacesRemoved(logWatchPath),
152 std::bind(selRemovedCallback, std::placeholders::_1));
153 }
Lei YU4106e422021-09-15 10:55:51 +0800154 if (!selUpdatedMatch)
155 {
156 selUpdatedMatch = std::make_unique<sdbusplus::bus::match::match>(
157 bus,
158 type::signal() + member("PropertiesChanged"s) +
159 interface("org.freedesktop.DBus.Properties"s) +
160 argN(0, logEntryIntf),
161 std::bind(selUpdatedCallback, std::placeholders::_1));
162 }
Lei YUd9555252021-09-14 20:30:41 +0800163}
164
Lei YUd9e57662021-09-14 18:06:28 +0800165void initSELCache()
166{
Lei YUeba8e9a2021-09-15 13:16:17 +0800167 ipmi::sel::ObjectPaths paths;
Lei YUd9e57662021-09-14 18:06:28 +0800168 try
169 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800170 ipmi::sel::readLoggingObjectPaths(paths);
Lei YUd9e57662021-09-14 18:06:28 +0800171 }
172 catch (const sdbusplus::exception::exception& e)
173 {
174 log<level::ERR>("Failed to get logging object paths");
175 return;
176 }
Lei YUeba8e9a2021-09-15 13:16:17 +0800177 for (const auto& p : paths)
Lei YUd9e57662021-09-14 18:06:28 +0800178 {
179 selCacheMap.insert(parseLoggingEntry(p));
180 }
Lei YUd9555252021-09-14 20:30:41 +0800181 registerSelCallbackHandler();
Lei YU3df36612021-09-15 11:41:11 +0800182 selCacheMapInitialized = true;
Lei YUd9e57662021-09-14 18:06:28 +0800183}
184
Marri Devender Raocac383b2017-07-03 13:24:27 -0500185/**
186 * @enum Device access mode
187 */
188enum class AccessMode
189{
190 bytes, ///< Device is accessed by bytes
191 words ///< Device is accessed by words
192};
193
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000194/** @brief implements the get SEL Info command
195 * @returns IPMI completion code plus response data
196 * - selVersion - SEL revision
197 * - entries - Number of log entries in SEL.
198 * - freeSpace - Free Space in bytes.
199 * - addTimeStamp - Most recent addition timestamp
200 * - eraseTimeStamp - Most recent erase timestamp
201 * - operationSupport - Reserve & Delete SEL operations supported
202 */
203
204ipmi::RspType<uint8_t, // SEL revision.
205 uint16_t, // number of log entries in SEL.
206 uint16_t, // free Space in bytes.
207 uint32_t, // most recent addition timestamp
208 uint32_t, // most recent erase timestamp.
209
210 bool, // SEL allocation info supported
211 bool, // reserve SEL supported
212 bool, // partial Add SEL Entry supported
213 bool, // delete SEL supported
214 uint3_t, // reserved
215 bool // overflow flag
216 >
217 ipmiStorageGetSelInfo()
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530218{
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000219 uint16_t entries = 0;
220 // Most recent addition timestamp.
221 uint32_t addTimeStamp = ipmi::sel::invalidTimeStamp;
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530222
Lei YUeba8e9a2021-09-15 13:16:17 +0800223 if (!selCacheMapInitialized)
Tom Josephe59abfb2018-08-06 18:46:27 +0530224 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800225 // In case the initSELCache() fails, try it again
226 initSELCache();
Tom Josephe59abfb2018-08-06 18:46:27 +0530227 }
Lei YUeba8e9a2021-09-15 13:16:17 +0800228 if (!selCacheMap.empty())
Tom Josephe59abfb2018-08-06 18:46:27 +0530229 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800230 entries = static_cast<uint16_t>(selCacheMap.size());
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530231
232 try
233 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800234 auto objPath = getLoggingObjPath(selCacheMap.rbegin()->first);
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000235 addTimeStamp = static_cast<uint32_t>(
Lei YUeba8e9a2021-09-15 13:16:17 +0800236 (ipmi::sel::getEntryTimeStamp(objPath).count()));
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530237 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500238 catch (const InternalFailure& e)
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530239 {
240 }
241 catch (const std::runtime_error& e)
242 {
243 log<level::ERR>(e.what());
244 }
245 }
246
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000247 constexpr uint8_t selVersion = ipmi::sel::selVersion;
248 constexpr uint16_t freeSpace = 0xFFFF;
249 constexpr uint32_t eraseTimeStamp = ipmi::sel::invalidTimeStamp;
250 constexpr uint3_t reserved{0};
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530251
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000252 return ipmi::responseSuccess(
253 selVersion, entries, freeSpace, addTimeStamp, eraseTimeStamp,
254 ipmi::sel::operationSupport::getSelAllocationInfo,
255 ipmi::sel::operationSupport::reserveSel,
256 ipmi::sel::operationSupport::partialAddSelEntry,
257 ipmi::sel::operationSupport::deleteSel, reserved,
258 ipmi::sel::operationSupport::overflow);
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530259}
260
Tom Josepha4953392017-06-30 19:09:47 +0530261ipmi_ret_t getSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
262 ipmi_request_t request, ipmi_response_t response,
263 ipmi_data_len_t data_len, ipmi_context_t context)
264{
Jason M. Bills851acb12019-02-04 14:06:57 -0800265 if (*data_len != sizeof(ipmi::sel::GetSELEntryRequest))
266 {
267 *data_len = 0;
268 return IPMI_CC_REQ_DATA_LEN_INVALID;
269 }
270
Patrick Venture0b02be92018-08-31 11:55:55 -0700271 auto requestData =
272 reinterpret_cast<const ipmi::sel::GetSELEntryRequest*>(request);
Tom Josepha4953392017-06-30 19:09:47 +0530273
274 if (requestData->reservationID != 0)
275 {
Jason M. Bills13e67c82018-09-10 14:12:16 -0700276 if (!checkSELReservation(requestData->reservationID))
Tom Josepha4953392017-06-30 19:09:47 +0530277 {
278 *data_len = 0;
279 return IPMI_CC_INVALID_RESERVATION_ID;
280 }
281 }
282
Lei YU3df36612021-09-15 11:41:11 +0800283 if (!selCacheMapInitialized)
284 {
285 // In case the initSELCache() fails, try it again
286 initSELCache();
287 }
288
289 if (selCacheMap.empty())
Tom Josepha4953392017-06-30 19:09:47 +0530290 {
291 *data_len = 0;
292 return IPMI_CC_SENSOR_INVALID;
293 }
294
Lei YU3df36612021-09-15 11:41:11 +0800295 SELCacheMap::const_iterator iter;
Tom Josepha4953392017-06-30 19:09:47 +0530296
297 // Check for the requested SEL Entry.
298 if (requestData->selRecordID == ipmi::sel::firstEntry)
299 {
Lei YU3df36612021-09-15 11:41:11 +0800300 iter = selCacheMap.begin();
Tom Josepha4953392017-06-30 19:09:47 +0530301 }
302 else if (requestData->selRecordID == ipmi::sel::lastEntry)
303 {
Lei YU3df36612021-09-15 11:41:11 +0800304 if (selCacheMap.size() > 1)
305 {
306 iter = selCacheMap.end();
307 --iter;
308 }
309 else
310 {
311 // Only one entry exists, return the first
312 iter = selCacheMap.begin();
313 }
Tom Josepha4953392017-06-30 19:09:47 +0530314 }
315 else
316 {
Lei YU3df36612021-09-15 11:41:11 +0800317 iter = selCacheMap.find(requestData->selRecordID);
318 if (iter == selCacheMap.end())
Tom Josepha4953392017-06-30 19:09:47 +0530319 {
320 *data_len = 0;
321 return IPMI_CC_SENSOR_INVALID;
322 }
323 }
324
Lei YU3df36612021-09-15 11:41:11 +0800325 ipmi::sel::GetSELEntryResponse record{0, iter->second};
Tom Josepha4953392017-06-30 19:09:47 +0530326 // Identify the next SEL record ID
Lei YU3df36612021-09-15 11:41:11 +0800327 ++iter;
328 if (iter == selCacheMap.end())
Tom Josepha4953392017-06-30 19:09:47 +0530329 {
Lei YU3df36612021-09-15 11:41:11 +0800330 record.nextRecordID = ipmi::sel::lastEntry;
Tom Josepha4953392017-06-30 19:09:47 +0530331 }
332 else
333 {
Lei YU3df36612021-09-15 11:41:11 +0800334 record.nextRecordID = iter->first;
Tom Josepha4953392017-06-30 19:09:47 +0530335 }
336
337 if (requestData->readLength == ipmi::sel::entireRecord)
338 {
Patrick Ventureb51bf9c2018-09-10 15:53:14 -0700339 std::memcpy(response, &record, sizeof(record));
Tom Josepha4953392017-06-30 19:09:47 +0530340 *data_len = sizeof(record);
341 }
342 else
343 {
344 if (requestData->offset >= ipmi::sel::selRecordSize ||
345 requestData->readLength > ipmi::sel::selRecordSize)
346 {
347 *data_len = 0;
348 return IPMI_CC_INVALID_FIELD_REQUEST;
349 }
350
351 auto diff = ipmi::sel::selRecordSize - requestData->offset;
Patrick Venture0b02be92018-08-31 11:55:55 -0700352 auto readLength =
353 std::min(diff, static_cast<int>(requestData->readLength));
Tom Josepha4953392017-06-30 19:09:47 +0530354
Patrick Ventureb51bf9c2018-09-10 15:53:14 -0700355 std::memcpy(response, &record.nextRecordID,
356 sizeof(record.nextRecordID));
357 std::memcpy(static_cast<uint8_t*>(response) +
358 sizeof(record.nextRecordID),
Lei YUaf378fa2020-12-02 16:28:57 +0800359 &record.event.eventRecord.recordID + requestData->offset,
360 readLength);
Tom Josepha4953392017-06-30 19:09:47 +0530361 *data_len = sizeof(record.nextRecordID) + readLength;
362 }
363
364 return IPMI_CC_OK;
365}
366
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000367/** @brief implements the delete SEL entry command
368 * @request
369 * - reservationID; // reservation ID.
370 * - selRecordID; // SEL record ID.
371 *
372 * @returns ipmi completion code plus response data
373 * - Record ID of the deleted record
374 */
375ipmi::RspType<uint16_t // deleted record ID
376 >
377 deleteSELEntry(uint16_t reservationID, uint16_t selRecordID)
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530378{
Jason M. Bills851acb12019-02-04 14:06:57 -0800379
Brad Bishop1a4117b2018-11-21 15:48:18 -0500380 namespace fs = std::filesystem;
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530381
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000382 if (!checkSELReservation(reservationID))
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530383 {
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000384 return ipmi::responseInvalidReservationId();
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530385 }
386
Jason M. Bills13e67c82018-09-10 14:12:16 -0700387 // Per the IPMI spec, need to cancel the reservation when a SEL entry is
388 // deleted
389 cancelSELReservation();
390
Lei YUeba8e9a2021-09-15 13:16:17 +0800391 if (!selCacheMapInitialized)
Tom Josephe59abfb2018-08-06 18:46:27 +0530392 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800393 // In case the initSELCache() fails, try it again
394 initSELCache();
Tom Josephe59abfb2018-08-06 18:46:27 +0530395 }
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530396
Lei YUeba8e9a2021-09-15 13:16:17 +0800397 if (selCacheMap.empty())
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530398 {
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000399 return ipmi::responseSensorInvalid();
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530400 }
401
Lei YUeba8e9a2021-09-15 13:16:17 +0800402 SELCacheMap::const_iterator iter;
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530403 uint16_t delRecordID = 0;
404
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000405 if (selRecordID == ipmi::sel::firstEntry)
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530406 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800407 delRecordID = selCacheMap.begin()->first;
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530408 }
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000409 else if (selRecordID == ipmi::sel::lastEntry)
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530410 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800411 delRecordID = selCacheMap.rbegin()->first;
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530412 }
413 else
414 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800415 iter = selCacheMap.find(selRecordID);
416 if (iter == selCacheMap.end())
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530417 {
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000418 return ipmi::responseSensorInvalid();
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530419 }
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000420 delRecordID = selRecordID;
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530421 }
422
423 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
424 std::string service;
425
Lei YUeba8e9a2021-09-15 13:16:17 +0800426 auto objPath = getLoggingObjPath(iter->first);
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530427 try
428 {
Lei YUeba8e9a2021-09-15 13:16:17 +0800429 service = ipmi::getService(bus, ipmi::sel::logDeleteIntf, objPath);
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530430 }
431 catch (const std::runtime_error& e)
432 {
433 log<level::ERR>(e.what());
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000434 return ipmi::responseUnspecifiedError();
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530435 }
436
Lei YUeba8e9a2021-09-15 13:16:17 +0800437 auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
Patrick Venture0b02be92018-08-31 11:55:55 -0700438 ipmi::sel::logDeleteIntf, "Delete");
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530439 auto reply = bus.call(methodCall);
440 if (reply.is_method_error())
441 {
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000442 return ipmi::responseUnspecifiedError();
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530443 }
444
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000445 return ipmi::responseSuccess(delRecordID);
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530446}
447
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000448/** @brief implements the Clear SEL command
449 * @request
450 * - reservationID // Reservation ID.
451 * - clr // char array { 'C'(0x43h), 'L'(0x4Ch), 'R'(0x52h) }
452 * - eraseOperation; // requested operation.
453 *
454 * @returns ipmi completion code plus response data
455 * - erase status
456 */
457
458ipmi::RspType<uint8_t // erase status
459 >
460 clearSEL(uint16_t reservationID, const std::array<char, 3>& clr,
461 uint8_t eraseOperation)
Tom Joseph2f05bb52017-06-30 19:14:49 +0530462{
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000463 static constexpr std::array<char, 3> clrOk = {'C', 'L', 'R'};
464 if (clr != clrOk)
Jason M. Bills851acb12019-02-04 14:06:57 -0800465 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000466 return ipmi::responseInvalidFieldRequest();
Jason M. Bills851acb12019-02-04 14:06:57 -0800467 }
468
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000469 if (!checkSELReservation(reservationID))
Tom Joseph2f05bb52017-06-30 19:14:49 +0530470 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000471 return ipmi::responseInvalidReservationId();
Tom Joseph2f05bb52017-06-30 19:14:49 +0530472 }
473
Tom Joseph2f05bb52017-06-30 19:14:49 +0530474 /*
475 * Erasure status cannot be fetched from DBUS, so always return erasure
476 * status as `erase completed`.
477 */
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000478 if (eraseOperation == ipmi::sel::getEraseStatus)
Tom Joseph2f05bb52017-06-30 19:14:49 +0530479 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000480 return ipmi::responseSuccess(
481 static_cast<uint8_t>(ipmi::sel::eraseComplete));
Tom Joseph2f05bb52017-06-30 19:14:49 +0530482 }
483
Jason M. Bills13e67c82018-09-10 14:12:16 -0700484 // Per the IPMI spec, need to cancel any reservation when the SEL is cleared
485 cancelSELReservation();
486
Tom Joseph2f05bb52017-06-30 19:14:49 +0530487 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Tom Josephe59abfb2018-08-06 18:46:27 +0530488 ipmi::sel::ObjectPaths objectPaths;
Tom Joseph2f05bb52017-06-30 19:14:49 +0530489 auto depth = 0;
490
Patrick Venture0b02be92018-08-31 11:55:55 -0700491 auto mapperCall =
492 bus.new_method_call(ipmi::sel::mapperBusName, ipmi::sel::mapperObjPath,
493 ipmi::sel::mapperIntf, "GetSubTreePaths");
Tom Joseph2f05bb52017-06-30 19:14:49 +0530494 mapperCall.append(ipmi::sel::logBasePath);
495 mapperCall.append(depth);
496 mapperCall.append(ipmi::sel::ObjectPaths({ipmi::sel::logEntryIntf}));
497
Tom Josephe59abfb2018-08-06 18:46:27 +0530498 try
Tom Joseph2f05bb52017-06-30 19:14:49 +0530499 {
Tom Josephe59abfb2018-08-06 18:46:27 +0530500 auto reply = bus.call(mapperCall);
501 if (reply.is_method_error())
502 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000503 return ipmi::responseSuccess(
504 static_cast<uint8_t>(ipmi::sel::eraseComplete));
Tom Josephe59abfb2018-08-06 18:46:27 +0530505 }
Tom Joseph2f05bb52017-06-30 19:14:49 +0530506
Tom Josephe59abfb2018-08-06 18:46:27 +0530507 reply.read(objectPaths);
508 if (objectPaths.empty())
509 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000510 return ipmi::responseSuccess(
511 static_cast<uint8_t>(ipmi::sel::eraseComplete));
Tom Josephe59abfb2018-08-06 18:46:27 +0530512 }
513 }
Patrick Williamsef1259b2021-09-02 09:12:33 -0500514 catch (const sdbusplus::exception::exception& e)
Tom Joseph2f05bb52017-06-30 19:14:49 +0530515 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000516 return ipmi::responseSuccess(
517 static_cast<uint8_t>(ipmi::sel::eraseComplete));
Tom Joseph2f05bb52017-06-30 19:14:49 +0530518 }
519
520 std::string service;
521
522 try
523 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700524 service = ipmi::getService(bus, ipmi::sel::logDeleteIntf,
Tom Joseph2f05bb52017-06-30 19:14:49 +0530525 objectPaths.front());
526 }
527 catch (const std::runtime_error& e)
528 {
529 log<level::ERR>(e.what());
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000530 return ipmi::responseUnspecifiedError();
Tom Joseph2f05bb52017-06-30 19:14:49 +0530531 }
532
533 for (const auto& iter : objectPaths)
534 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700535 auto methodCall = bus.new_method_call(
536 service.c_str(), iter.c_str(), ipmi::sel::logDeleteIntf, "Delete");
Tom Joseph2f05bb52017-06-30 19:14:49 +0530537
538 auto reply = bus.call(methodCall);
539 if (reply.is_method_error())
540 {
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000541 return ipmi::responseUnspecifiedError();
Tom Joseph2f05bb52017-06-30 19:14:49 +0530542 }
543 }
544
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000545 return ipmi::responseSuccess(
546 static_cast<uint8_t>(ipmi::sel::eraseComplete));
Tom Joseph2f05bb52017-06-30 19:14:49 +0530547}
548
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000549/** @brief implements the get SEL time command
550 * @returns IPMI completion code plus response data
551 * -current time
552 */
553ipmi::RspType<uint32_t> // current time
554 ipmiStorageGetSelTime()
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500555{
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530556 using namespace std::chrono;
George Liu4d623e92020-05-25 16:51:57 +0800557 uint64_t bmc_time_usec = 0;
558 std::stringstream bmcTime;
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500559
Lei YUe8939392017-06-15 10:45:05 +0800560 try
561 {
562 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
George Liu4d623e92020-05-25 16:51:57 +0800563 auto service = ipmi::getService(bus, TIME_INTERFACE, BMC_TIME_PATH);
Vernon Mauery16b86932019-05-01 08:36:11 -0700564 std::variant<uint64_t> value;
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530565
George Liu4d623e92020-05-25 16:51:57 +0800566 // Get bmc time
567 auto method = bus.new_method_call(service.c_str(), BMC_TIME_PATH,
Patrick Venture0b02be92018-08-31 11:55:55 -0700568 DBUS_PROPERTIES, "Get");
Lei YUe8939392017-06-15 10:45:05 +0800569
570 method.append(TIME_INTERFACE, PROPERTY_ELAPSED);
571 auto reply = bus.call(method);
572 if (reply.is_method_error())
573 {
574 log<level::ERR>("Error getting time",
575 entry("SERVICE=%s", service.c_str()),
George Liu4d623e92020-05-25 16:51:57 +0800576 entry("PATH=%s", BMC_TIME_PATH));
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000577 return ipmi::responseUnspecifiedError();
Lei YUe8939392017-06-15 10:45:05 +0800578 }
579 reply.read(value);
George Liu4d623e92020-05-25 16:51:57 +0800580 bmc_time_usec = std::get<uint64_t>(value);
Lei YUe8939392017-06-15 10:45:05 +0800581 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500582 catch (const InternalFailure& e)
Lei YUe8939392017-06-15 10:45:05 +0800583 {
584 log<level::ERR>(e.what());
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000585 return ipmi::responseUnspecifiedError();
Lei YUe8939392017-06-15 10:45:05 +0800586 }
Tom Joseph30fd0a12019-09-24 06:53:22 +0530587 catch (const std::exception& e)
Lei YUe8939392017-06-15 10:45:05 +0800588 {
589 log<level::ERR>(e.what());
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000590 return ipmi::responseUnspecifiedError();
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530591 }
592
George Liu4d623e92020-05-25 16:51:57 +0800593 bmcTime << "BMC time:"
594 << duration_cast<seconds>(microseconds(bmc_time_usec)).count();
595 log<level::DEBUG>(bmcTime.str().c_str());
Nagaraju Goruganti8960b7c2018-04-29 22:38:40 -0500596
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530597 // Time is really long int but IPMI wants just uint32. This works okay until
598 // the number of seconds since 1970 overflows uint32 size.. Still a whole
599 // lot of time here to even think about that.
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000600 return ipmi::responseSuccess(
George Liu4d623e92020-05-25 16:51:57 +0800601 duration_cast<seconds>(microseconds(bmc_time_usec)).count());
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500602}
603
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000604/** @brief implements the set SEL time command
605 * @param selDeviceTime - epoch time
606 * -local time as the number of seconds from 00:00:00, January 1, 1970
607 * @returns IPMI completion code
608 */
609ipmi::RspType<> ipmiStorageSetSelTime(uint32_t selDeviceTime)
Chris Austenb4f5b922015-10-13 12:44:43 -0500610{
Lei YUe8939392017-06-15 10:45:05 +0800611 using namespace std::chrono;
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000612 microseconds usec{seconds(selDeviceTime)};
Norman James82330442015-11-19 16:53:26 -0600613
Lei YUe8939392017-06-15 10:45:05 +0800614 try
615 {
616 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
George Liu4d623e92020-05-25 16:51:57 +0800617 auto service = ipmi::getService(bus, TIME_INTERFACE, BMC_TIME_PATH);
Andrew Geissler6467ed22020-05-16 16:03:53 -0500618 std::variant<uint64_t> value{(uint64_t)usec.count()};
Lei YUe8939392017-06-15 10:45:05 +0800619
George Liu4d623e92020-05-25 16:51:57 +0800620 // Set bmc time
621 auto method = bus.new_method_call(service.c_str(), BMC_TIME_PATH,
Patrick Venture0b02be92018-08-31 11:55:55 -0700622 DBUS_PROPERTIES, "Set");
Lei YUe8939392017-06-15 10:45:05 +0800623
624 method.append(TIME_INTERFACE, PROPERTY_ELAPSED, value);
625 auto reply = bus.call(method);
626 if (reply.is_method_error())
627 {
628 log<level::ERR>("Error setting time",
629 entry("SERVICE=%s", service.c_str()),
George Liu4d623e92020-05-25 16:51:57 +0800630 entry("PATH=%s", BMC_TIME_PATH));
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000631 return ipmi::responseUnspecifiedError();
Lei YUe8939392017-06-15 10:45:05 +0800632 }
Norman James82330442015-11-19 16:53:26 -0600633 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500634 catch (const InternalFailure& e)
Lei YUe8939392017-06-15 10:45:05 +0800635 {
636 log<level::ERR>(e.what());
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000637 return ipmi::responseUnspecifiedError();
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530638 }
Tom Joseph30fd0a12019-09-24 06:53:22 +0530639 catch (const std::exception& e)
Lei YUe8939392017-06-15 10:45:05 +0800640 {
641 log<level::ERR>(e.what());
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000642 return ipmi::responseUnspecifiedError();
Norman James82330442015-11-19 16:53:26 -0600643 }
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530644
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000645 return ipmi::responseSuccess();
Chris Austenb4f5b922015-10-13 12:44:43 -0500646}
647
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000648/** @brief implements the reserve SEL command
649 * @returns IPMI completion code plus response data
650 * - SEL reservation ID.
651 */
652ipmi::RspType<uint16_t> ipmiStorageReserveSel()
Chris Austenb4f5b922015-10-13 12:44:43 -0500653{
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000654 return ipmi::responseSuccess(reserveSel());
Chris Austenb4f5b922015-10-13 12:44:43 -0500655}
656
anil kumar appana2c7db1d2019-05-28 11:20:19 +0000657/** @brief implements the Add SEL entry command
658 * @request
659 *
660 * - recordID ID used for SEL Record access
661 * - recordType Record Type
662 * - timeStamp Time when event was logged. LS byte first
663 * - generatorID software ID if event was generated from
664 * system software
665 * - evmRev event message format version
666 * - sensorType sensor type code for service that generated
667 * the event
668 * - sensorNumber number of sensors that generated the event
669 * - eventDir event dir
670 * - eventData event data field contents
671 *
672 * @returns ipmi completion code plus response data
673 * - RecordID of the Added SEL entry
674 */
675ipmi::RspType<uint16_t // recordID of the Added SEL entry
676 >
677 ipmiStorageAddSEL(uint16_t recordID, uint8_t recordType, uint32_t timeStamp,
678 uint16_t generatorID, uint8_t evmRev, uint8_t sensorType,
679 uint8_t sensorNumber, uint8_t eventDir,
680 std::array<uint8_t, eventDataSize> eventData)
Chris Austenb4f5b922015-10-13 12:44:43 -0500681{
Jason M. Bills13e67c82018-09-10 14:12:16 -0700682 // Per the IPMI spec, need to cancel the reservation when a SEL entry is
683 // added
684 cancelSELReservation();
Tom Josephb647d5b2017-10-31 17:25:33 +0530685 // Hostboot sends SEL with OEM record type 0xDE to indicate that there is
686 // a maintenance procedure associated with eSEL record.
687 static constexpr auto procedureType = 0xDE;
anil kumar appana2c7db1d2019-05-28 11:20:19 +0000688 if (recordType == procedureType)
Tom Josephb647d5b2017-10-31 17:25:33 +0530689 {
690 // In the OEM record type 0xDE, byte 11 in the SEL record indicate the
691 // procedure number.
anil kumar appana2c7db1d2019-05-28 11:20:19 +0000692 createProcedureLogEntry(sensorType);
Tom Josephb647d5b2017-10-31 17:25:33 +0530693 }
Chris Austenb4f5b922015-10-13 12:44:43 -0500694
anil kumar appana2c7db1d2019-05-28 11:20:19 +0000695 return ipmi::responseSuccess(recordID);
Chris Austenb4f5b922015-10-13 12:44:43 -0500696}
697
Kirill Pakhomovfa6e2092020-04-24 18:57:15 +0300698bool isFruPresent(const std::string& fruPath)
699{
700 using namespace ipmi::fru;
701
702 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
703
704 auto propValue =
705 ipmi::getDbusProperty(bus, invMgrInterface, invObjPath + fruPath,
706 invItemInterface, itemPresentProp);
707
708 return std::get<bool>(propValue);
709}
710
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000711/** @brief implements the get FRU Inventory Area Info command
712 *
713 * @returns IPMI completion code plus response data
714 * - FRU Inventory area size in bytes,
715 * - access bit
716 **/
717ipmi::RspType<uint16_t, // FRU Inventory area size in bytes,
718 uint8_t // access size (bytes / words)
719 >
720 ipmiStorageGetFruInvAreaInfo(uint8_t fruID)
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500721{
Tom Joseph187f5642018-03-29 13:49:06 +0530722
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000723 auto iter = frus.find(fruID);
Tom Joseph187f5642018-03-29 13:49:06 +0530724 if (iter == frus.end())
725 {
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000726 return ipmi::responseSensorInvalid();
Tom Joseph187f5642018-03-29 13:49:06 +0530727 }
728
Kirill Pakhomovfa6e2092020-04-24 18:57:15 +0300729 auto path = iter->second[0].path;
730 if (!isFruPresent(path))
731 {
732 return ipmi::responseSensorInvalid();
733 }
734
Marri Devender Raocac383b2017-07-03 13:24:27 -0500735 try
736 {
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000737 return ipmi::responseSuccess(
738 static_cast<uint16_t>(getFruAreaData(fruID).size()),
739 static_cast<uint8_t>(AccessMode::bytes));
Marri Devender Raocac383b2017-07-03 13:24:27 -0500740 }
Patrick Venture0b02be92018-08-31 11:55:55 -0700741 catch (const InternalFailure& e)
Marri Devender Raocac383b2017-07-03 13:24:27 -0500742 {
Marri Devender Raocac383b2017-07-03 13:24:27 -0500743 log<level::ERR>(e.what());
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000744 return ipmi::responseUnspecifiedError();
Marri Devender Raocac383b2017-07-03 13:24:27 -0500745 }
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500746}
747
anil kumar appana5b7c3262019-05-27 18:10:23 +0000748/**@brief implements the Read FRU Data command
749 * @param fruDeviceId - FRU device ID. FFh = reserved
750 * @param offset - FRU inventory offset to read
751 * @param readCount - count to read
752 *
753 * @return IPMI completion code plus response data
754 * - returnCount - response data count.
755 * - data - response data
756 */
757ipmi::RspType<uint8_t, // count returned
758 std::vector<uint8_t>> // FRU data
759 ipmiStorageReadFruData(uint8_t fruDeviceId, uint16_t offset,
760 uint8_t readCount)
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500761{
anil kumar appana5b7c3262019-05-27 18:10:23 +0000762 if (fruDeviceId == 0xFF)
Tom Joseph187f5642018-03-29 13:49:06 +0530763 {
anil kumar appana5b7c3262019-05-27 18:10:23 +0000764 return ipmi::responseInvalidFieldRequest();
Tom Joseph187f5642018-03-29 13:49:06 +0530765 }
766
anil kumar appana5b7c3262019-05-27 18:10:23 +0000767 auto iter = frus.find(fruDeviceId);
768 if (iter == frus.end())
769 {
770 return ipmi::responseSensorInvalid();
771 }
772
Marri Devender Raocac383b2017-07-03 13:24:27 -0500773 try
774 {
anil kumar appana5b7c3262019-05-27 18:10:23 +0000775 const auto& fruArea = getFruAreaData(fruDeviceId);
Marri Devender Raocac383b2017-07-03 13:24:27 -0500776 auto size = fruArea.size();
Nagaraju Goruganti7f2d7c92018-03-21 11:18:30 -0500777
Tom Josephefcd68b2018-04-26 18:46:27 +0530778 if (offset >= size)
779 {
anil kumar appana5b7c3262019-05-27 18:10:23 +0000780 return ipmi::responseParmOutOfRange();
Tom Josephefcd68b2018-04-26 18:46:27 +0530781 }
782
Nagaraju Goruganti7f2d7c92018-03-21 11:18:30 -0500783 // Write the count of response data.
anil kumar appana5b7c3262019-05-27 18:10:23 +0000784 uint8_t returnCount;
785 if ((offset + readCount) <= size)
Marri Devender Raocac383b2017-07-03 13:24:27 -0500786 {
anil kumar appana5b7c3262019-05-27 18:10:23 +0000787 returnCount = readCount;
Nagaraju Goruganti7f2d7c92018-03-21 11:18:30 -0500788 }
789 else
790 {
anil kumar appana5b7c3262019-05-27 18:10:23 +0000791 returnCount = size - offset;
Marri Devender Raocac383b2017-07-03 13:24:27 -0500792 }
Ratan Gupta2848d602018-01-31 20:39:20 +0530793
anil kumar appana5b7c3262019-05-27 18:10:23 +0000794 std::vector<uint8_t> fruData((fruArea.begin() + offset),
795 (fruArea.begin() + offset + returnCount));
Ratan Gupta2848d602018-01-31 20:39:20 +0530796
anil kumar appana5b7c3262019-05-27 18:10:23 +0000797 return ipmi::responseSuccess(returnCount, fruData);
Marri Devender Raocac383b2017-07-03 13:24:27 -0500798 }
799 catch (const InternalFailure& e)
800 {
Marri Devender Raocac383b2017-07-03 13:24:27 -0500801 log<level::ERR>(e.what());
anil kumar appana5b7c3262019-05-27 18:10:23 +0000802 return ipmi::responseUnspecifiedError();
Marri Devender Raocac383b2017-07-03 13:24:27 -0500803 }
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500804}
805
Pradeep Kumarb60e8402019-05-06 15:17:01 +0000806ipmi::RspType<uint8_t, // SDR version
807 uint16_t, // record count LS first
808 uint16_t, // free space in bytes, LS first
809 uint32_t, // addition timestamp LS first
810 uint32_t, // deletion timestamp LS first
811 uint8_t> // operation Support
812 ipmiGetRepositoryInfo()
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600813{
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600814
Pradeep Kumarb60e8402019-05-06 15:17:01 +0000815 constexpr uint8_t sdrVersion = 0x51;
816 constexpr uint16_t freeSpace = 0xFFFF;
817 constexpr uint32_t additionTimestamp = 0x0;
818 constexpr uint32_t deletionTimestamp = 0x0;
819 constexpr uint8_t operationSupport = 0;
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600820
Patrick Venturedb0cbe62019-09-09 14:47:22 -0700821 uint16_t records = frus.size() + ipmi::sensor::sensors.size();
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600822
Pradeep Kumarb60e8402019-05-06 15:17:01 +0000823 return ipmi::responseSuccess(sdrVersion, records, freeSpace,
824 additionTimestamp, deletionTimestamp,
825 operationSupport);
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600826}
Chris Austenb4f5b922015-10-13 12:44:43 -0500827
Chris Austenb4f5b922015-10-13 12:44:43 -0500828void register_netfn_storage_functions()
829{
Lei YU3df36612021-09-15 11:41:11 +0800830 selCacheMapInitialized = false;
Lei YUd9e57662021-09-14 18:06:28 +0800831 initSELCache();
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530832 // <Get SEL Info>
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000833 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
834 ipmi::storage::cmdGetSelInfo, ipmi::Privilege::User,
835 ipmiStorageGetSelInfo);
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530836
Tom05732372016-09-06 17:21:23 +0530837 // <Get SEL Time>
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000838 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
839 ipmi::storage::cmdGetSelTime, ipmi::Privilege::User,
840 ipmiStorageGetSelTime);
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500841
Tom05732372016-09-06 17:21:23 +0530842 // <Set SEL Time>
jayaprakash Mutyaladb2e8c42019-05-03 01:38:01 +0000843 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
844 ipmi::storage::cmdSetSelTime,
845 ipmi::Privilege::Operator, ipmiStorageSetSelTime);
Chris Austenb4f5b922015-10-13 12:44:43 -0500846
Tom05732372016-09-06 17:21:23 +0530847 // <Reserve SEL>
jayaprakash Mutyalab7557722019-05-02 21:13:30 +0000848 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
849 ipmi::storage::cmdReserveSel, ipmi::Privilege::User,
850 ipmiStorageReserveSel);
Tom Josepha4953392017-06-30 19:09:47 +0530851 // <Get SEL Entry>
Patrick Venture0b02be92018-08-31 11:55:55 -0700852 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_ENTRY, NULL,
853 getSELEntry, PRIVILEGE_USER);
Tom Josepha4953392017-06-30 19:09:47 +0530854
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530855 // <Delete SEL Entry>
Pradeep Kumar00a18d02019-04-26 17:04:28 +0000856 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
857 ipmi::storage::cmdDeleteSelEntry,
858 ipmi::Privilege::Operator, deleteSELEntry);
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530859
Tom05732372016-09-06 17:21:23 +0530860 // <Add SEL Entry>
anil kumar appana2c7db1d2019-05-28 11:20:19 +0000861 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
862 ipmi::storage::cmdAddSelEntry,
863 ipmi::Privilege::Operator, ipmiStorageAddSEL);
864
Tom Joseph2f05bb52017-06-30 19:14:49 +0530865 // <Clear SEL>
Pradeep Kumar4a5a99a2019-04-26 15:22:39 +0000866 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
867 ipmi::storage::cmdClearSel, ipmi::Privilege::Operator,
868 clearSEL);
869
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500870 // <Get FRU Inventory Area Info>
Pradeep Kumarb0c794d2019-05-02 13:09:14 +0000871 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
872 ipmi::storage::cmdGetFruInventoryAreaInfo,
873 ipmi::Privilege::User, ipmiStorageGetFruInvAreaInfo);
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500874
Jason M. Billsb5248c92019-06-24 15:53:08 -0700875 // <READ FRU Data>
anil kumar appana5b7c3262019-05-27 18:10:23 +0000876 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
877 ipmi::storage::cmdReadFruData,
878 ipmi::Privilege::Operator, ipmiStorageReadFruData);
Marri Devender Raocac383b2017-07-03 13:24:27 -0500879
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600880 // <Get Repository Info>
Pradeep Kumarb60e8402019-05-06 15:17:01 +0000881 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
882 ipmi::storage::cmdGetSdrRepositoryInfo,
883 ipmi::Privilege::User, ipmiGetRepositoryInfo);
Dhruvaraj Subhashchandrane66c3b02018-02-07 01:21:56 -0600884
Tom Joseph5ca50952018-02-22 00:33:38 +0530885 // <Reserve SDR Repository>
jayaprakash Mutyalad9578232019-05-13 20:22:50 +0000886 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
887 ipmi::storage::cmdReserveSdrRepository,
888 ipmi::Privilege::User, ipmiSensorReserveSdr);
Tom Joseph5ca50952018-02-22 00:33:38 +0530889
890 // <Get SDR>
Patrick Venture0b02be92018-08-31 11:55:55 -0700891 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SDR, nullptr,
892 ipmi_sen_get_sdr, PRIVILEGE_USER);
Tom Joseph5ca50952018-02-22 00:33:38 +0530893
Marri Devender Rao908f7502017-07-10 01:49:54 -0500894 ipmi::fru::registerCallbackHandler();
Chris Austenb4f5b922015-10-13 12:44:43 -0500895 return;
896}