blob: a1b3f03737ea7f2e61a0f62d5b6e5d92c5a31d9e [file] [log] [blame]
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +05301#include <cstdio>
2#include <string>
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -05003#include <arpa/inet.h>
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +05304#include <systemd/sd-bus.h>
5#include <mapper.h>
6#include <chrono>
Tom Joseph6f7deaa2017-06-30 19:03:54 +05307#include "selutility.hpp"
Chris Austen41a4b312015-10-25 03:45:42 -05008#include "storagehandler.h"
9#include "storageaddsel.h"
Tom Joseph8f4a2aa2017-06-30 19:12:49 +053010#include "utils.hpp"
Patrick Williams37af7332016-09-02 21:21:42 -050011#include "host-ipmid/ipmid-api.h"
Tom Josepha4953392017-06-30 19:09:47 +053012#include <experimental/filesystem>
Tom Joseph6f7deaa2017-06-30 19:03:54 +053013#include <phosphor-logging/log.hpp>
14#include <sdbusplus/server.hpp>
15#include "xyz/openbmc_project/Common/error.hpp"
Chris Austen41a4b312015-10-25 03:45:42 -050016
Chris Austenb4f5b922015-10-13 12:44:43 -050017void register_netfn_storage_functions() __attribute__((constructor));
18
19
20unsigned int g_sel_time = 0xFFFFFFFF;
Nan Li36c0cb62016-03-31 11:16:08 +080021extern unsigned short g_sel_reserve;
Chris Austenb4f5b922015-10-13 12:44:43 -050022
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +053023constexpr auto time_manager_intf = "org.openbmc.TimeManager";
24constexpr auto time_manager_obj = "/org/openbmc/TimeManager";
25
Tom Joseph6f7deaa2017-06-30 19:03:54 +053026namespace cache
27{
28 /*
29 * This cache contains the object paths of the logging entries sorted in the
30 * order of the filename(numeric order). The cache is initialized by
31 * invoking readLoggingObjectPaths with the cache as the parameter. The
32 * cache is invoked in the execution of the Get SEL info and Delete SEL
33 * entry command. The Get SEL Info command is typically invoked before the
34 * Get SEL entry command, so the cache is utilized for responding to Get SEL
35 * entry command. The cache is invalidated by clearing after Delete SEL
36 * entry and Clear SEL command.
37 */
38 ipmi::sel::ObjectPaths paths;
39
40} // namespace objectPathsCache
41
42using InternalFailure =
43 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
44using namespace phosphor::logging;
45
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -050046ipmi_ret_t ipmi_storage_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
47 ipmi_request_t request, ipmi_response_t response,
Chris Austenb4f5b922015-10-13 12:44:43 -050048 ipmi_data_len_t data_len, ipmi_context_t context)
49{
50 printf("Handling STORAGE WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
51 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +080052 ipmi_ret_t rc = IPMI_CC_INVALID;
Chris Austenb4f5b922015-10-13 12:44:43 -050053 *data_len = 0;
54 return rc;
55}
56
Tom Joseph6f7deaa2017-06-30 19:03:54 +053057ipmi_ret_t getSELInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
58 ipmi_request_t request, ipmi_response_t response,
59 ipmi_data_len_t data_len, ipmi_context_t context)
60{
61 std::vector<uint8_t> outPayload(sizeof(ipmi::sel::GetSELInfoResponse));
62 auto responseData = reinterpret_cast<ipmi::sel::GetSELInfoResponse*>
63 (outPayload.data());
64
65 responseData->selVersion = ipmi::sel::selVersion;
66 // Last erase timestamp is not available from log manager.
67 responseData->eraseTimeStamp = ipmi::sel::invalidTimeStamp;
68 responseData->operationSupport = ipmi::sel::operationSupport;
69
70 ipmi::sel::readLoggingObjectPaths(cache::paths);
71 responseData->entries = 0;
72 responseData->addTimeStamp = ipmi::sel::invalidTimeStamp;
73
74 if (!cache::paths.empty())
75 {
76 responseData->entries = static_cast<uint16_t>(cache::paths.size());
77
78 try
79 {
80 responseData->addTimeStamp = static_cast<uint32_t>(
81 (ipmi::sel::getEntryTimeStamp(cache::paths.back())
82 .count()));
83 }
84 catch (InternalFailure& e)
85 {
86 }
87 catch (const std::runtime_error& e)
88 {
89 log<level::ERR>(e.what());
90 }
91 }
92
93 memcpy(response, outPayload.data(), outPayload.size());
94 *data_len = outPayload.size();
95
96 return IPMI_CC_OK;
97}
98
Tom Josepha4953392017-06-30 19:09:47 +053099ipmi_ret_t getSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
100 ipmi_request_t request, ipmi_response_t response,
101 ipmi_data_len_t data_len, ipmi_context_t context)
102{
103 auto requestData = reinterpret_cast<const ipmi::sel::GetSELEntryRequest*>
104 (request);
105
106 if (requestData->reservationID != 0)
107 {
108 if (g_sel_reserve != requestData->reservationID)
109 {
110 *data_len = 0;
111 return IPMI_CC_INVALID_RESERVATION_ID;
112 }
113 }
114
115 if (cache::paths.empty())
116 {
117 *data_len = 0;
118 return IPMI_CC_SENSOR_INVALID;
119 }
120
121 ipmi::sel::ObjectPaths::const_iterator iter;
122
123 // Check for the requested SEL Entry.
124 if (requestData->selRecordID == ipmi::sel::firstEntry)
125 {
126 iter = cache::paths.begin();
127 }
128 else if (requestData->selRecordID == ipmi::sel::lastEntry)
129 {
130 iter = cache::paths.end();
131 }
132 else
133 {
134 std::string objPath = std::string(ipmi::sel::logBasePath) + "/" +
135 std::to_string(requestData->selRecordID);
136
137 iter = std::find(cache::paths.begin(), cache::paths.end(), objPath);
138 if (iter == cache::paths.end())
139 {
140 *data_len = 0;
141 return IPMI_CC_SENSOR_INVALID;
142 }
143 }
144
145 ipmi::sel::GetSELEntryResponse record {};
146
147 // Convert the log entry into SEL record.
148 try
149 {
150 record = ipmi::sel::convertLogEntrytoSEL(*iter);
151 }
152 catch (InternalFailure& e)
153 {
154 *data_len = 0;
155 return IPMI_CC_UNSPECIFIED_ERROR;
156 }
157 catch (const std::runtime_error& e)
158 {
159 log<level::ERR>(e.what());
160 *data_len = 0;
161 return IPMI_CC_UNSPECIFIED_ERROR;
162 }
163
164
165 // Identify the next SEL record ID
166 if(iter != cache::paths.end())
167 {
168 ++iter;
169 if (iter == cache::paths.end())
170 {
171 record.nextRecordID = ipmi::sel::lastEntry;
172 }
173 else
174 {
175 namespace fs = std::experimental::filesystem;
176 fs::path path(*iter);
177 record.nextRecordID = static_cast<uint16_t>
178 (std::stoul(std::string(path.filename().c_str())));
179 }
180 }
181 else
182 {
183 record.nextRecordID = ipmi::sel::lastEntry;
184 }
185
186 if (requestData->readLength == ipmi::sel::entireRecord)
187 {
188 memcpy(response, &record, sizeof(record));
189 *data_len = sizeof(record);
190 }
191 else
192 {
193 if (requestData->offset >= ipmi::sel::selRecordSize ||
194 requestData->readLength > ipmi::sel::selRecordSize)
195 {
196 *data_len = 0;
197 return IPMI_CC_INVALID_FIELD_REQUEST;
198 }
199
200 auto diff = ipmi::sel::selRecordSize - requestData->offset;
201 auto readLength = std::min(diff,
202 static_cast<int>(requestData->readLength));
203
204 memcpy(response, &record.nextRecordID, sizeof(record.nextRecordID));
205 memcpy(static_cast<uint8_t*>(response) + sizeof(record.nextRecordID),
206 &record.recordID + requestData->offset, readLength);
207 *data_len = sizeof(record.nextRecordID) + readLength;
208 }
209
210 return IPMI_CC_OK;
211}
212
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530213ipmi_ret_t deleteSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
214 ipmi_request_t request, ipmi_response_t response,
215 ipmi_data_len_t data_len, ipmi_context_t context)
216{
217 namespace fs = std::experimental::filesystem;
218 auto requestData = reinterpret_cast<const ipmi::sel::DeleteSELEntryRequest*>
219 (request);
220
221 if (g_sel_reserve != requestData->reservationID)
222 {
223 *data_len = 0;
224 return IPMI_CC_INVALID_RESERVATION_ID;
225 }
226
227 ipmi::sel::readLoggingObjectPaths(cache::paths);
228
229 if (cache::paths.empty())
230 {
231 *data_len = 0;
232 return IPMI_CC_SENSOR_INVALID;
233 }
234
235 ipmi::sel::ObjectPaths::const_iterator iter;
236 uint16_t delRecordID = 0;
237
238 if (requestData->selRecordID == ipmi::sel::firstEntry)
239 {
240 iter = cache::paths.begin();
241 fs::path path(*iter);
242 delRecordID = static_cast<uint16_t>
243 (std::stoul(std::string(path.filename().c_str())));
244 }
245 else if (requestData->selRecordID == ipmi::sel::lastEntry)
246 {
247 iter = cache::paths.end();
248 fs::path path(*iter);
249 delRecordID = static_cast<uint16_t>
250 (std::stoul(std::string(path.filename().c_str())));
251 }
252 else
253 {
254 std::string objPath = std::string(ipmi::sel::logBasePath) + "/" +
255 std::to_string(requestData->selRecordID);
256
257 iter = std::find(cache::paths.begin(), cache::paths.end(), objPath);
258 if (iter == cache::paths.end())
259 {
260 *data_len = 0;
261 return IPMI_CC_SENSOR_INVALID;
262 }
263 delRecordID = requestData->selRecordID;
264 }
265
266 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
267 std::string service;
268
269 try
270 {
271 service = ipmi::getService(bus, ipmi::sel::logDeleteIntf, *iter);
272 }
273 catch (const std::runtime_error& e)
274 {
275 log<level::ERR>(e.what());
276 *data_len = 0;
277 return IPMI_CC_UNSPECIFIED_ERROR;
278 }
279
280 auto methodCall = bus.new_method_call(service.c_str(),
281 (*iter).c_str(),
282 ipmi::sel::logDeleteIntf,
283 "Delete");
284 auto reply = bus.call(methodCall);
285 if (reply.is_method_error())
286 {
287 *data_len = 0;
288 return IPMI_CC_UNSPECIFIED_ERROR;
289 }
290
291 // Invalidate the cache of dbus entry objects.
292 cache::paths.clear();
293 memcpy(response, &delRecordID, sizeof(delRecordID));
294 *data_len = sizeof(delRecordID);
295
296 return IPMI_CC_OK;
297}
298
Tom Joseph2f05bb52017-06-30 19:14:49 +0530299ipmi_ret_t clearSEL(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
300 ipmi_response_t response, ipmi_data_len_t data_len,
301 ipmi_context_t context)
302{
303 auto requestData = reinterpret_cast<const ipmi::sel::ClearSELRequest*>
304 (request);
305
306 if (g_sel_reserve != requestData->reservationID)
307 {
308 *data_len = 0;
309 return IPMI_CC_INVALID_RESERVATION_ID;
310 }
311
312 if (requestData->charC != 'C' ||
313 requestData->charL != 'L' ||
314 requestData->charR != 'R')
315 {
316 *data_len = 0;
317 return IPMI_CC_INVALID_FIELD_REQUEST;
318 }
319
320 uint8_t eraseProgress = ipmi::sel::eraseComplete;
321
322 /*
323 * Erasure status cannot be fetched from DBUS, so always return erasure
324 * status as `erase completed`.
325 */
326 if (requestData->eraseOperation == ipmi::sel::getEraseStatus)
327 {
328 memcpy(response, &eraseProgress, sizeof(eraseProgress));
329 *data_len = sizeof(eraseProgress);
330 return IPMI_CC_OK;
331 }
332
333 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
334 auto depth = 0;
335
336 auto mapperCall = bus.new_method_call(ipmi::sel::mapperBusName,
337 ipmi::sel::mapperObjPath,
338 ipmi::sel::mapperIntf,
339 "GetSubTreePaths");
340 mapperCall.append(ipmi::sel::logBasePath);
341 mapperCall.append(depth);
342 mapperCall.append(ipmi::sel::ObjectPaths({ipmi::sel::logEntryIntf}));
343
344 auto reply = bus.call(mapperCall);
345 if (reply.is_method_error())
346 {
347 memcpy(response, &eraseProgress, sizeof(eraseProgress));
348 *data_len = sizeof(eraseProgress);
349 return IPMI_CC_OK;
350 }
351
352 ipmi::sel::ObjectPaths objectPaths;
353 reply.read(objectPaths);
354 if (objectPaths.empty())
355 {
356 memcpy(response, &eraseProgress, sizeof(eraseProgress));
357 *data_len = sizeof(eraseProgress);
358 return IPMI_CC_OK;
359 }
360
361 std::string service;
362
363 try
364 {
365 service = ipmi::getService(bus,
366 ipmi::sel::logDeleteIntf,
367 objectPaths.front());
368 }
369 catch (const std::runtime_error& e)
370 {
371 log<level::ERR>(e.what());
372 *data_len = 0;
373 return IPMI_CC_UNSPECIFIED_ERROR;
374 }
375
376 for (const auto& iter : objectPaths)
377 {
378 auto methodCall = bus.new_method_call(service.c_str(),
379 iter.c_str(),
380 ipmi::sel::logDeleteIntf,
381 "Delete");
382
383 auto reply = bus.call(methodCall);
384 if (reply.is_method_error())
385 {
386 *data_len = 0;
387 return IPMI_CC_UNSPECIFIED_ERROR;
388 }
389 }
390
391 // Invalidate the cache of dbus entry objects.
392 cache::paths.clear();
393 memcpy(response, &eraseProgress, sizeof(eraseProgress));
394 *data_len = sizeof(eraseProgress);
395 return IPMI_CC_OK;
396}
397
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500398ipmi_ret_t ipmi_storage_get_sel_time(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
399 ipmi_request_t request, ipmi_response_t response,
400 ipmi_data_len_t data_len, ipmi_context_t context)
401{
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530402 using namespace std::chrono;
403
404 char *time_provider = nullptr;
405 const char* time_in_str = nullptr;
406 uint64_t host_time_usec = 0;
407 uint32_t resp = 0;
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500408 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austenb4f5b922015-10-13 12:44:43 -0500409
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530410 sd_bus_message *reply = nullptr;
411 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500412
413 printf("IPMI Handling GET-SEL-TIME\n");
414
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530415 auto bus = ipmid_get_sd_bus_connection();
416
417 auto rct = mapper_get_service(bus, time_manager_obj, &time_provider);
418 if (rct < 0) {
419 printf("Error [%s] getting bus name for time provider\n",
420 strerror(-rct));
421 rc = IPMI_CC_UNSPECIFIED_ERROR;
422 goto finish;
423 }
424
425 rct = sd_bus_call_method(bus,
426 time_provider,
427 time_manager_obj,
428 time_manager_intf,
429 "GetTime",
430 &bus_error,
431 &reply,
432 "s",
433 "host");
434 if (rct < 0) {
435 printf("Error [%s] getting time\n", strerror(-rct));
436 rc = IPMI_CC_UNSPECIFIED_ERROR;
437 goto finish;
438 }
439
440 rct = sd_bus_message_read(reply, "sx", &time_in_str, &host_time_usec);
441 if (rct < 0) {
442 fprintf(stderr, "Error [%s] parsing get-time response\n",
443 strerror(-rct));
444 rc = IPMI_CC_UNSPECIFIED_ERROR;
445 goto finish;
446 }
447
448 // Time is really long int but IPMI wants just uint32. This works okay until
449 // the number of seconds since 1970 overflows uint32 size.. Still a whole
450 // lot of time here to even think about that.
451 resp = duration_cast<seconds>(microseconds(host_time_usec)).count();
452 resp = htole32(resp);
453 printf("Host Time read:[%s] :: [%d]\n", time_in_str, resp);
454
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500455 // From the IPMI Spec 2.0, response should be a 32-bit value
456 *data_len = sizeof(resp);
457
458 // Pack the actual response
459 memcpy(response, &resp, *data_len);
460
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530461finish:
462 sd_bus_error_free(&bus_error);
463 reply = sd_bus_message_unref(reply);
464 free(time_provider);
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500465 return rc;
466}
467
468ipmi_ret_t ipmi_storage_set_sel_time(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
469 ipmi_request_t request, ipmi_response_t response,
Chris Austenb4f5b922015-10-13 12:44:43 -0500470 ipmi_data_len_t data_len, ipmi_context_t context)
471{
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530472 char *time_provider = nullptr;
473 int time_rc = 0;
474 ipmi_ret_t rc = IPMI_CC_OK;
475
476 sd_bus_message *reply = nullptr;
477 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
478
Norman James82330442015-11-19 16:53:26 -0600479 uint32_t* secs = (uint32_t*)request;
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530480 *data_len = 0;
Chris Austenb4f5b922015-10-13 12:44:43 -0500481
482 printf("Handling Set-SEL-Time:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
Norman James82330442015-11-19 16:53:26 -0600483 printf("Data: 0x%X]\n",*secs);
Chris Austenb4f5b922015-10-13 12:44:43 -0500484
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530485 auto bus = ipmid_get_sd_bus_connection();
Norman James82330442015-11-19 16:53:26 -0600486
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530487 auto rct = mapper_get_service(bus, time_manager_obj, &time_provider);
488 if (rct < 0) {
489 printf("Error [%s] getting bus name for time provider\n",
490 strerror(-rct));
491 rc = IPMI_CC_UNSPECIFIED_ERROR;
492 goto finish;
Norman James82330442015-11-19 16:53:26 -0600493 }
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530494
495 rct = sd_bus_call_method(bus,
496 time_provider,
497 time_manager_obj,
498 time_manager_intf,
499 "SetTime",
500 &bus_error,
501 &reply,
502 "ss",
503 "host",
504 std::to_string(le32toh(*secs)).c_str());
505
506 if (rct < 0) {
507 printf("Error [%s] setting time\n", strerror(-rct));
508 rc = IPMI_CC_UNSPECIFIED_ERROR;
509 goto finish;
510 }
511
512 rct = sd_bus_message_read(reply, "i", &time_rc);
513 if (rct < 0) {
514 fprintf(stderr, "Error [%s] parsing set-time response\n",
515 strerror(-rct));
516 rc = IPMI_CC_UNSPECIFIED_ERROR;
517 goto finish;
518 }
519
520 if (time_rc < 0) {
521 printf("Error setting time.");
Norman James82330442015-11-19 16:53:26 -0600522 rc = IPMI_CC_UNSPECIFIED_ERROR;
523 }
Vishwanatha Subbanna5fba7a62016-09-01 14:06:07 +0530524
525finish:
526 sd_bus_error_free(&bus_error);
527 reply = sd_bus_message_unref(reply);
528 free(time_provider);
Chris Austenb4f5b922015-10-13 12:44:43 -0500529 return rc;
530}
531
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500532ipmi_ret_t ipmi_storage_reserve_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
533 ipmi_request_t request, ipmi_response_t response,
Chris Austenb4f5b922015-10-13 12:44:43 -0500534 ipmi_data_len_t data_len, ipmi_context_t context)
535{
Chris Austenb4f5b922015-10-13 12:44:43 -0500536 ipmi_ret_t rc = IPMI_CC_OK;
537
Nan Li36c0cb62016-03-31 11:16:08 +0800538 // IPMI spec, Reservation ID, the value simply increases against each execution of reserve_sel command.
539 if( ++g_sel_reserve == 0)
540 g_sel_reserve = 1;
Chris Austenb4f5b922015-10-13 12:44:43 -0500541
Nan Li36c0cb62016-03-31 11:16:08 +0800542 printf("IPMI Handling RESERVE-SEL 0x%04x\n", g_sel_reserve);
Chris Austen41a4b312015-10-25 03:45:42 -0500543
Chris Austenb4f5b922015-10-13 12:44:43 -0500544 *data_len = sizeof(g_sel_reserve);
545
546 // Pack the actual response
547 memcpy(response, &g_sel_reserve, *data_len);
548
549 return rc;
550}
551
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500552ipmi_ret_t ipmi_storage_add_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
553 ipmi_request_t request, ipmi_response_t response,
Chris Austenb4f5b922015-10-13 12:44:43 -0500554 ipmi_data_len_t data_len, ipmi_context_t context)
555{
556
557 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austen41a4b312015-10-25 03:45:42 -0500558 ipmi_add_sel_request_t *p = (ipmi_add_sel_request_t*) request;
559 uint16_t recordid;
Chris Austenb4f5b922015-10-13 12:44:43 -0500560
Chris Austen313d95b2015-10-31 12:55:30 -0500561 recordid = ((uint16_t)p->eventdata[1] << 8) | p->eventdata[2];
Chris Austen41a4b312015-10-25 03:45:42 -0500562
563 printf("IPMI Handling ADD-SEL for record 0x%04x\n", recordid);
Chris Austenb4f5b922015-10-13 12:44:43 -0500564
565 *data_len = sizeof(g_sel_reserve);
566
567 // Pack the actual response
Chris Austen7cc33322015-11-11 00:20:22 -0600568 memcpy(response, &p->eventdata[1], 2);
Chris Austenb4f5b922015-10-13 12:44:43 -0500569
Chris Austen41a4b312015-10-25 03:45:42 -0500570 send_esel(recordid);
Chris Austenb4f5b922015-10-13 12:44:43 -0500571
572 return rc;
573}
574
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500575//Read FRU info area
576ipmi_ret_t ipmi_storage_get_fru_inv_area_info(
577 ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
578 ipmi_response_t response, ipmi_data_len_t data_len,
579 ipmi_context_t context)
580{
581 ipmi_ret_t rc = IPMI_CC_OK;
582 return rc;
583}
584
585//Read FRU data
586ipmi_ret_t ipmi_storage_read_fru_data(
587 ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
588 ipmi_response_t response, ipmi_data_len_t data_len,
589 ipmi_context_t context)
590{
591 ipmi_ret_t rc = IPMI_CC_OK;
592 return rc;
593}
594
Chris Austenb4f5b922015-10-13 12:44:43 -0500595
596
597void register_netfn_storage_functions()
598{
Tom05732372016-09-06 17:21:23 +0530599 // <Wildcard Command>
Chris Austenb4f5b922015-10-13 12:44:43 -0500600 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +0530601 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_WILDCARD, NULL, ipmi_storage_wildcard,
602 PRIVILEGE_USER);
Chris Austenb4f5b922015-10-13 12:44:43 -0500603
Tom Joseph6f7deaa2017-06-30 19:03:54 +0530604 // <Get SEL Info>
605 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO);
606 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO, NULL, getSELInfo,
607 PRIVILEGE_USER);
608
Tom05732372016-09-06 17:21:23 +0530609 // <Get SEL Time>
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500610 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_TIME);
Tom05732372016-09-06 17:21:23 +0530611 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_TIME, NULL, ipmi_storage_get_sel_time,
612 PRIVILEGE_USER);
Adriana Kobylak8e30f2a2015-10-20 10:23:51 -0500613
Tom05732372016-09-06 17:21:23 +0530614 // <Set SEL Time>
Chris Austenb4f5b922015-10-13 12:44:43 -0500615 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_SET_SEL_TIME);
Tom05732372016-09-06 17:21:23 +0530616 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_SET_SEL_TIME, NULL, ipmi_storage_set_sel_time,
617 PRIVILEGE_OPERATOR);
Chris Austenb4f5b922015-10-13 12:44:43 -0500618
Tom05732372016-09-06 17:21:23 +0530619 // <Reserve SEL>
Chris Austenb4f5b922015-10-13 12:44:43 -0500620 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL);
Tom05732372016-09-06 17:21:23 +0530621 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL, NULL, ipmi_storage_reserve_sel,
622 PRIVILEGE_USER);
Chris Austenb4f5b922015-10-13 12:44:43 -0500623
Tom Josepha4953392017-06-30 19:09:47 +0530624 // <Get SEL Entry>
625 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_ENTRY);
626 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_ENTRY, NULL, getSELEntry,
627 PRIVILEGE_USER);
628
Tom Joseph8f4a2aa2017-06-30 19:12:49 +0530629 // <Delete SEL Entry>
630 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_DELETE_SEL);
631 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_DELETE_SEL, NULL, deleteSELEntry,
632 PRIVILEGE_OPERATOR);
633
Tom05732372016-09-06 17:21:23 +0530634 // <Add SEL Entry>
Chris Austenb4f5b922015-10-13 12:44:43 -0500635 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_ADD_SEL);
Tom05732372016-09-06 17:21:23 +0530636 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_ADD_SEL, NULL, ipmi_storage_add_sel,
637 PRIVILEGE_OPERATOR);
Tom Joseph2f05bb52017-06-30 19:14:49 +0530638 // <Clear SEL>
639 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_CLEAR_SEL);
640 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_CLEAR_SEL, NULL, clearSEL,
641 PRIVILEGE_OPERATOR);
Marri Devender Raofa7b4e22017-07-03 00:52:20 -0500642 // <Get FRU Inventory Area Info>
643 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_STORAGE,
644 IPMI_CMD_GET_FRU_INV_AREA_INFO);
645 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_FRU_INV_AREA_INFO, NULL,
646 ipmi_storage_get_fru_inv_area_info, PRIVILEGE_OPERATOR);
647
648 // <Add READ FRU Data
649 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_STORAGE,
650 IPMI_CMD_READ_FRU_DATA);
651
652 ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_READ_FRU_DATA, NULL,
653 ipmi_storage_read_fru_data, PRIVILEGE_OPERATOR);
Chris Austenb4f5b922015-10-13 12:44:43 -0500654 return;
655}
656