blob: 80e8620968c84c226bc97bb11c2de6b7aa040848 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#include <errno.h>
Vernon Mauerya3702c12019-05-22 13:20:59 -070018
19#include <commandutils.hpp>
20#include <cstdint>
Vernon Mauery15419dd2019-05-24 09:40:30 -070021#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070022#include <ipmid/utils.hpp>
23#include <phosphor-ipmi-host/ipmid.hpp>
24#include <phosphor-logging/elog-errors.hpp>
25#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070026#include <smbiosmdrv2.hpp>
27#include <string>
28#include <vector>
29#include <xyz/openbmc_project/Common/error.hpp>
30
31constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
32constexpr const char* MDRV2_PATH = "/xyz/openbmc_project/Smbios/MDR_V2";
33constexpr const char* MDRV2_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V2";
34constexpr const int LAST_AGENT_INDEX = -1;
35constexpr const uint16_t LAST_AGENT_ID = 0xFFFF;
36
37static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070038
Vernon Maueryc7d517e2019-06-18 14:27:00 -070039int gentLookup(const uint16_t& agentId, const std::string& service)
Vernon Mauerya3702c12019-05-22 13:20:59 -070040{
41 int agentIndex = -1;
42
43 if (LAST_AGENT_ID == agentId)
44 {
45 return LAST_AGENT_INDEX;
46 }
47
Vernon Mauery15419dd2019-05-24 09:40:30 -070048 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
49 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -070050 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "AgentLookup");
51 method.append(agentId);
Vernon Mauery15419dd2019-05-24 09:40:30 -070052 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070053 if (reply.is_method_error())
54 {
55 phosphor::logging::log<phosphor::logging::level::ERR>(
56 "Error get agent index, sdbusplus call failed");
57 return -1;
58 }
59 reply.read(agentIndex);
60
61 return agentIndex;
62}
63
64int findLockHandle(const uint16_t& lockHandle, const std::string& service)
65{
66 int idIndex = -1;
Vernon Mauery15419dd2019-05-24 09:40:30 -070067 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
68 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -070069 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "FindLockHandle");
70 method.append(lockHandle);
71
Vernon Mauery15419dd2019-05-24 09:40:30 -070072 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070073 if (reply.is_method_error())
74 {
75 phosphor::logging::log<phosphor::logging::level::ERR>(
76 "Error find lock handle",
77 phosphor::logging::entry("SERVICE=%s", service.c_str()),
78 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
79 return -1;
80 }
81 reply.read(idIndex);
82
83 return idIndex;
84}
85
86int sdplusMdrv2GetProperty(const std::string& name,
87 sdbusplus::message::variant<uint8_t>& value,
88 const std::string& service)
89{
Vernon Mauery15419dd2019-05-24 09:40:30 -070090 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
91 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -070092 service.c_str(), MDRV2_PATH, DBUS_PROPERTIES, "Get");
93 method.append(MDRV2_INTERFACE, name);
Vernon Mauery15419dd2019-05-24 09:40:30 -070094 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070095 if (reply.is_method_error())
96 {
97 phosphor::logging::log<phosphor::logging::level::ERR>(
98 "Error get property, sdbusplus call failed");
99 return -1;
100 }
101 reply.read(value);
102
103 return 0;
104}
105
106int findDataId(const uint8_t* dataInfo, const size_t& len,
107 const std::string& service)
108{
109 int idIndex = -1;
Vernon Mauery15419dd2019-05-24 09:40:30 -0700110 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
111 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700112 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "FindIdIndex");
113 std::vector<uint8_t> info;
114 for (int index = 0; index < len; index++)
115 {
116 info.push_back(dataInfo[index]);
117 }
118 method.append(info);
119
Vernon Mauery15419dd2019-05-24 09:40:30 -0700120 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700121 if (reply.is_method_error())
122 {
123 phosphor::logging::log<phosphor::logging::level::ERR>(
124 "Error find id index",
125 phosphor::logging::entry("SERVICE=%s", service.c_str()),
126 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
127 return -1;
128 }
129 reply.read(idIndex);
130
131 return idIndex;
132}
133
134ipmi_ret_t cmd_mdr2_agent_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
135 ipmi_request_t request,
136 ipmi_response_t response,
137 ipmi_data_len_t data_len,
138 ipmi_context_t context)
139{
140 auto requestData = reinterpret_cast<const MDRiiGetAgentStatus*>(request);
141 auto dataOut = reinterpret_cast<uint8_t*>(response);
142 std::vector<uint8_t> status;
143
144 if (*data_len != sizeof(MDRiiGetAgentStatus))
145 {
146 *data_len = 0;
147 return IPMI_CC_REQ_DATA_LEN_INVALID;
148 }
149
150 *data_len = 0;
151
Vernon Mauery15419dd2019-05-24 09:40:30 -0700152 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
153 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700154
155 int agentIndex = agentLookup(requestData->agentId, service);
156 if (agentIndex == -1)
157 {
158 phosphor::logging::log<phosphor::logging::level::ERR>(
159 "Unknown agent id",
160 phosphor::logging::entry("ID=%x", requestData->agentId));
161 return IPMI_CC_PARM_OUT_OF_RANGE;
162 }
163
Vernon Mauery15419dd2019-05-24 09:40:30 -0700164 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700165 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "AgentStatus");
166 method.append(requestData->dirVersion);
Vernon Mauery15419dd2019-05-24 09:40:30 -0700167 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700168 if (reply.is_method_error())
169 {
170 phosphor::logging::log<phosphor::logging::level::ERR>(
171 "Error get agent status",
172 phosphor::logging::entry("SERVICE=%s", service.c_str()),
173 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
174 return IPMI_CC_UNSPECIFIED_ERROR;
175 }
176 reply.read(status);
177
178 if (status.size() != sizeof(MDRiiAgentStatusResponse))
179 {
180 phosphor::logging::log<phosphor::logging::level::ERR>(
181 "Get agent status response length not valid");
182 return IPMI_CC_UNSPECIFIED_ERROR;
183 }
184 *data_len = static_cast<size_t>(status.size());
185 std::copy(&status[0], &status[*data_len], dataOut);
186 return IPMI_CC_OK;
187}
188
189ipmi_ret_t cmd_mdr2_get_dir(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
190 ipmi_request_t request, ipmi_response_t response,
191 ipmi_data_len_t data_len, ipmi_context_t context)
192{
193 auto requestData = reinterpret_cast<const MDRiiGetDirRequest*>(request);
194 auto dataOut = reinterpret_cast<uint8_t*>(response);
195 std::vector<uint8_t> dirInfo;
196
197 if (*data_len != sizeof(MDRiiGetDirRequest))
198 {
199 *data_len = 0;
200 return IPMI_CC_REQ_DATA_LEN_INVALID;
201 }
202
203 *data_len = 0;
204
Vernon Mauery15419dd2019-05-24 09:40:30 -0700205 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
206 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700207
208 int agentIndex = agentLookup(requestData->agentId, service);
209 if (agentIndex == -1)
210 {
211 phosphor::logging::log<phosphor::logging::level::ERR>(
212 "Unknown agent id",
213 phosphor::logging::entry("ID=%x", requestData->agentId));
214 return IPMI_CC_PARM_OUT_OF_RANGE;
215 }
216
217 sdbusplus::message::variant<uint8_t> value = 0;
218 if (0 != sdplusMdrv2GetProperty("DirEntries", value, service))
219 {
220 phosphor::logging::log<phosphor::logging::level::ERR>(
221 "Error getting DirEnries");
222 return IPMI_CC_UNSPECIFIED_ERROR;
223 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700224 if (requestData->dirIndex > std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700225 {
226 return IPMI_CC_PARM_OUT_OF_RANGE;
227 }
228
Vernon Mauery15419dd2019-05-24 09:40:30 -0700229 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700230 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDir");
231
232 method.append(requestData->dirIndex);
233
Vernon Mauery15419dd2019-05-24 09:40:30 -0700234 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700235 if (reply.is_method_error())
236 {
237 phosphor::logging::log<phosphor::logging::level::ERR>(
238 "Error get dir",
239 phosphor::logging::entry("SERVICE=%s", service.c_str()),
240 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
241 return IPMI_CC_UNSPECIFIED_ERROR;
242 }
243 reply.read(dirInfo);
244
245 if (dirInfo.size() < sizeof(MDRiiGetDirResponse))
246 {
247 phosphor::logging::log<phosphor::logging::level::ERR>(
248 "Error get dir, response length invalid");
249 return IPMI_CC_UNSPECIFIED_ERROR;
250 }
251
252 auto responseData = reinterpret_cast<MDRiiGetDirResponse*>(dirInfo.data());
253
254 *data_len = dirInfo.size();
255
256 if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
257 // than MAX_IPMI_BUFFER
258 {
259 phosphor::logging::log<phosphor::logging::level::ERR>(
260 "Data length send from service is invalid");
261 *data_len = 0;
262 return IPMI_CC_RESPONSE_ERROR;
263 }
264
265 std::copy(&dirInfo[0], &dirInfo[*data_len], dataOut);
266
267 return IPMI_CC_OK;
268}
269
270ipmi_ret_t cmd_mdr2_get_data_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
271 ipmi_request_t request,
272 ipmi_response_t response,
273 ipmi_data_len_t data_len,
274 ipmi_context_t context)
275{
276 auto requestData =
277 reinterpret_cast<const MDRiiGetDataInfoRequest*>(request);
278 auto dataOut = reinterpret_cast<uint8_t*>(response);
279 std::vector<uint8_t> res;
280
281 if (*data_len < sizeof(MDRiiGetDataInfoRequest))
282 {
283 *data_len = 0;
284 return IPMI_CC_REQ_DATA_LEN_INVALID;
285 }
286
287 *data_len = 0;
288
Vernon Mauery15419dd2019-05-24 09:40:30 -0700289 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
290 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700291
292 int agentIndex = agentLookup(requestData->agentId, service);
293 if (agentIndex == -1)
294 {
295 phosphor::logging::log<phosphor::logging::level::ERR>(
296 "Unknown agent id",
297 phosphor::logging::entry("ID=%x", requestData->agentId));
298 return IPMI_CC_PARM_OUT_OF_RANGE;
299 }
300
301 int idIndex =
302 findDataId(requestData->dataSetInfo.dataInfo,
303 sizeof(requestData->dataSetInfo.dataInfo), service);
304
305 if ((idIndex < 0) || (idIndex >= maxDirEntries))
306 {
307 phosphor::logging::log<phosphor::logging::level::ERR>(
308 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
309 return IPMI_CC_PARM_OUT_OF_RANGE;
310 }
311
Vernon Mauery15419dd2019-05-24 09:40:30 -0700312 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700313 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataInfo");
314
315 method.append(idIndex);
316
Vernon Mauery15419dd2019-05-24 09:40:30 -0700317 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700318 if (reply.is_method_error())
319 {
320 phosphor::logging::log<phosphor::logging::level::ERR>(
321 "Error get data info",
322 phosphor::logging::entry("SERVICE=%s", service.c_str()),
323 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
324 return IPMI_CC_UNSPECIFIED_ERROR;
325 }
326 reply.read(res);
327
328 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
329 {
330 phosphor::logging::log<phosphor::logging::level::ERR>(
331 "Get data info response length not invalid");
332 return IPMI_CC_UNSPECIFIED_ERROR;
333 }
334 *data_len = static_cast<size_t>(res.size());
335 std::copy(&res[0], &res[*data_len], dataOut);
336
337 return IPMI_CC_OK;
338}
339
340ipmi_ret_t cmd_mdr2_lock_data(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
341 ipmi_request_t request, ipmi_response_t response,
342 ipmi_data_len_t data_len, ipmi_context_t context)
343{
344 auto requestData = reinterpret_cast<const MDRiiLockDataRequest*>(request);
345 auto responseData = reinterpret_cast<MDRiiLockDataResponse*>(response);
346
347 std::tuple<bool, uint8_t, uint16_t, uint32_t, uint32_t, uint32_t> res;
348
349 if (*data_len < sizeof(MDRiiLockDataRequest))
350 {
351 *data_len = 0;
352 return IPMI_CC_REQ_DATA_LEN_INVALID;
353 }
354
355 *data_len = 0;
356
Vernon Mauery15419dd2019-05-24 09:40:30 -0700357 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
358 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700359
360 int agentIndex = agentLookup(requestData->agentId, service);
361 if (agentIndex == -1)
362 {
363 phosphor::logging::log<phosphor::logging::level::ERR>(
364 "Unknown agent id",
365 phosphor::logging::entry("ID=%x", requestData->agentId));
366 return IPMI_CC_PARM_OUT_OF_RANGE;
367 }
368
369 int idIndex =
370 findDataId(requestData->dataSetInfo.dataInfo,
371 sizeof(requestData->dataSetInfo.dataInfo), service);
372
373 if ((idIndex < 0) || (idIndex >= maxDirEntries))
374 {
375 phosphor::logging::log<phosphor::logging::level::ERR>(
376 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
377 return IPMI_CC_PARM_OUT_OF_RANGE;
378 }
379
Vernon Mauery15419dd2019-05-24 09:40:30 -0700380 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700381 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "LockData");
382
383 method.append((uint8_t)idIndex, requestData->timeout);
384
Vernon Mauery15419dd2019-05-24 09:40:30 -0700385 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700386 if (reply.is_method_error())
387 {
388 if (reply.get_errno() == EBUSY)
389 {
390 phosphor::logging::log<phosphor::logging::level::ERR>(
391 "Lock Data failed - cannot lock idIndex");
392 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
393 }
394 phosphor::logging::log<phosphor::logging::level::ERR>(
395 "Error lock data",
396 phosphor::logging::entry("SERVICE=%s", service.c_str()),
397 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
398 return IPMI_CC_UNSPECIFIED_ERROR;
399 }
400 reply.read(res);
401
402 if (std::get<0>(res) == false)
403 {
404 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
405 }
406
407 *data_len = sizeof(MDRiiLockDataResponse);
408
409 responseData->mdrVersion = std::get<1>(res);
410 responseData->lockHandle = std::get<2>(res);
411 responseData->dataLength = std::get<3>(res);
412 responseData->xferAddress = std::get<4>(res);
413 responseData->xferLength = std::get<5>(res);
414
415 return IPMI_CC_OK;
416}
417
418ipmi_ret_t cmd_mdr2_unlock_data(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
419 ipmi_request_t request,
420 ipmi_response_t response,
421 ipmi_data_len_t data_len,
422 ipmi_context_t context)
423{
424 auto requestData = reinterpret_cast<const MDRiiUnlockDataRequest*>(request);
425 std::string resStatus;
426
427 if (*data_len != sizeof(MDRiiUnlockDataRequest))
428 {
429 *data_len = 0;
430 return IPMI_CC_REQ_DATA_LEN_INVALID;
431 }
432
433 *data_len = 0;
434
Vernon Mauery15419dd2019-05-24 09:40:30 -0700435 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
436 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700437
438 int agentIndex = agentLookup(requestData->agentId, service);
439 if (agentIndex == -1)
440 {
441 phosphor::logging::log<phosphor::logging::level::ERR>(
442 "Unknown agent id",
443 phosphor::logging::entry("ID=%x", requestData->agentId));
444 return IPMI_CC_PARM_OUT_OF_RANGE;
445 }
446
447 int idIndex = findLockHandle(requestData->lockHandle, service);
448
449 if ((idIndex < 0) || (idIndex >= maxDirEntries))
450 {
451 phosphor::logging::log<phosphor::logging::level::ERR>(
452 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
453 return IPMI_CC_PARM_OUT_OF_RANGE;
454 }
455
Vernon Mauery15419dd2019-05-24 09:40:30 -0700456 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700457 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "UnLockData");
458 method.append((uint8_t)idIndex);
459
Vernon Mauery15419dd2019-05-24 09:40:30 -0700460 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700461 if (reply.is_method_error())
462 {
463 if (reply.get_errno() == EBUSY)
464 {
465 phosphor::logging::log<phosphor::logging::level::ERR>(
466 "Unlock Data failed - cannot unlock idIndex");
467 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
468 }
469 phosphor::logging::log<phosphor::logging::level::ERR>(
470 "Error unlock data",
471 phosphor::logging::entry("SERVICE=%s", service.c_str()),
472 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
473 return IPMI_CC_UNSPECIFIED_ERROR;
474 }
475 reply.read(resStatus);
476
477 if (resStatus != "success")
478 {
479 phosphor::logging::log<phosphor::logging::level::ERR>(
480 "Agent unlock Invalid lock status.");
481 return IPMI_CC_UNSPECIFIED_ERROR;
482 }
483
484 return IPMI_CC_OK;
485}
486
487ipmi_ret_t cmd_mdr2_get_data_block(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
488 ipmi_request_t request,
489 ipmi_response_t response,
490 ipmi_data_len_t data_len,
491 ipmi_context_t context)
492{
493 auto requestData =
494 reinterpret_cast<const MDRiiGetDataBlockRequest*>(request);
495 auto responseData = reinterpret_cast<MDRiiGetDataBlockResponse*>(response);
496 std::tuple<uint8_t, uint32_t, uint32_t, std::vector<uint8_t>> res;
497 std::vector<uint8_t> resData;
498 uint8_t status = 1;
499
500 if (*data_len != sizeof(MDRiiGetDataBlockRequest))
501 {
502 *data_len = 0;
503 return IPMI_CC_REQ_DATA_LEN_INVALID;
504 }
505
506 *data_len = 0;
507
Vernon Mauery15419dd2019-05-24 09:40:30 -0700508 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
509 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700510
511 int agentIndex = agentLookup(requestData->agentId, service);
512 if (agentIndex == -1)
513 {
514 phosphor::logging::log<phosphor::logging::level::ERR>(
515 "Unknown agent id",
516 phosphor::logging::entry("ID=%x", requestData->agentId));
517 return IPMI_CC_PARM_OUT_OF_RANGE;
518 }
519
520 int idIndex = findLockHandle(requestData->lockHandle, service);
521
522 if ((idIndex < 0) || (idIndex >= maxDirEntries))
523 {
524 phosphor::logging::log<phosphor::logging::level::ERR>(
525 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
526 return IPMI_CC_PARM_OUT_OF_RANGE;
527 }
528
Vernon Mauery15419dd2019-05-24 09:40:30 -0700529 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700530 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataBlock");
531 method.append((uint8_t)idIndex, requestData->xferOffset,
532 requestData->xferLength);
533
Vernon Mauery15419dd2019-05-24 09:40:30 -0700534 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700535 if (reply.is_method_error())
536 {
537 phosphor::logging::log<phosphor::logging::level::ERR>(
538 "Error get data block",
539 phosphor::logging::entry("SERVICE=%s", service.c_str()),
540 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
541 return IPMI_CC_UNSPECIFIED_ERROR;
542 }
543 reply.read(res);
544
545 // Get the status of get data block, 0 means succeed
546 status = std::get<0>(res);
547 if (status == 1)
548 {
549 phosphor::logging::log<phosphor::logging::level::ERR>(
550 "Request data offset is outside of range.");
551 return IPMI_CC_CANNOT_RETURN_NUMBER_OF_REQUESTED_DATA_BYTES;
552 }
553 else if (status != 0)
554 {
555 phosphor::logging::log<phosphor::logging::level::ERR>(
556 "Get data block unexpected error.");
557 return IPMI_CC_UNSPECIFIED_ERROR;
558 }
559
560 responseData->xferLength = std::get<1>(res);
561 if (responseData->xferLength > requestData->xferLength)
562 {
563 phosphor::logging::log<phosphor::logging::level::ERR>(
564 "Get data block unexpected error.");
565 return IPMI_CC_UNSPECIFIED_ERROR;
566 }
567
568 responseData->checksum = std::get<2>(res);
569
570 resData = std::get<3>(res);
571
572 *data_len = sizeof(responseData->xferLength) +
573 sizeof(responseData->checksum) + resData.size();
574
575 if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
576 // than MAX_IPMI_BUFFER
577 {
578 phosphor::logging::log<phosphor::logging::level::ERR>(
579 "Data length send from service is invalid");
580 *data_len = 0;
581 return IPMI_CC_RESPONSE_ERROR;
582 }
583
584 std::copy(resData.begin(), resData.end(), responseData->data);
585
586 return IPMI_CC_OK;
587}
588
589ipmi_ret_t cmd_mdr2_send_dir(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
590 ipmi_request_t request, ipmi_response_t response,
591 ipmi_data_len_t data_len, ipmi_context_t context)
592{
593 auto requestData = reinterpret_cast<const MDRiiSendDirRequest*>(request);
594 std::vector<uint8_t> idVector;
595 bool teminate = false;
596
597 if (*data_len != sizeof(MDRiiSendDirRequest))
598 {
599 *data_len = 0;
600 return IPMI_CC_REQ_DATA_LEN_INVALID;
601 }
602
603 *data_len = 0;
604
Vernon Mauery15419dd2019-05-24 09:40:30 -0700605 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
606 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700607
608 int agentIndex = agentLookup(requestData->agentId, service);
609 if (agentIndex == -1)
610 {
611 phosphor::logging::log<phosphor::logging::level::ERR>(
612 "Unknown agent id",
613 phosphor::logging::entry("ID=%x", requestData->agentId));
614 return IPMI_CC_PARM_OUT_OF_RANGE;
615 }
616
617 if ((requestData->dirIndex + requestData->returnedEntries) > maxDirEntries)
618 {
619 phosphor::logging::log<phosphor::logging::level::ERR>(
620 "Too many directory entries");
621 return IPMI_CC_STORGE_LEAK;
622 }
623
Vernon Mauery15419dd2019-05-24 09:40:30 -0700624 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700625 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDir");
626 method.append(requestData->dirVersion, requestData->dirIndex,
627 requestData->returnedEntries, requestData->remainingEntries);
628 uint8_t* reqPoint;
629 for (int index = 0; index < requestData->returnedEntries; index++)
630 {
631 reqPoint = (uint8_t*)&(requestData->data[index]);
632 std::copy(reqPoint, sizeof(Mdr2DirEntry) + reqPoint, idVector.data());
633 }
634 method.append(idVector);
635
Vernon Mauery15419dd2019-05-24 09:40:30 -0700636 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700637 if (reply.is_method_error())
638 {
639 phosphor::logging::log<phosphor::logging::level::ERR>(
640 "Error send dir",
641 phosphor::logging::entry("SERVICE=%s", service.c_str()),
642 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
643 return IPMI_CC_UNSPECIFIED_ERROR;
644 }
645 reply.read(teminate);
646
647 *data_len = 1;
648 if (teminate == false)
649 *(static_cast<uint8_t*>(response)) = 0;
650 else
651 *(static_cast<uint8_t*>(response)) = 1;
652 return IPMI_CC_OK;
653}
654
655ipmi_ret_t cmd_mdr2_data_info_offer(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
656 ipmi_request_t request,
657 ipmi_response_t response,
658 ipmi_data_len_t data_len,
659 ipmi_context_t context)
660{
661 auto requestData = reinterpret_cast<const MDRiiOfferDataInfo*>(request);
662 auto dataOut = reinterpret_cast<uint8_t*>(response);
663 std::vector<uint8_t> dataInfo;
664
665 if (*data_len != sizeof(MDRiiOfferDataInfo))
666 {
667 *data_len = 0;
668 return IPMI_CC_REQ_DATA_LEN_INVALID;
669 }
670
671 *data_len = 0;
672
Vernon Mauery15419dd2019-05-24 09:40:30 -0700673 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
674 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700675
676 int agentIndex = agentLookup(requestData->agentId, service);
677 if (agentIndex == -1)
678 {
679 phosphor::logging::log<phosphor::logging::level::ERR>(
680 "Unknown agent id",
681 phosphor::logging::entry("ID=%x", requestData->agentId));
682 return IPMI_CC_PARM_OUT_OF_RANGE;
683 }
684
Vernon Mauery15419dd2019-05-24 09:40:30 -0700685 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700686 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "GetDataOffer");
687
Vernon Mauery15419dd2019-05-24 09:40:30 -0700688 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700689 if (reply.is_method_error())
690 {
691 if (reply.get_errno() == EBUSY)
692 {
693 phosphor::logging::log<phosphor::logging::level::ERR>(
694 "Send data info offer failed - not available to update data "
695 "into agent at present");
696 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
697 }
698 phosphor::logging::log<phosphor::logging::level::ERR>(
699 "Error send data info offer",
700 phosphor::logging::entry("SERVICE=%s", service.c_str()),
701 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
702 return IPMI_CC_UNSPECIFIED_ERROR;
703 }
704 reply.read(dataInfo);
705 if (dataInfo.size() != sizeof(MDRiiOfferDataInfoResponse))
706 {
707 phosphor::logging::log<phosphor::logging::level::ERR>(
708 "Error send data info offer, return length invalid");
709 return IPMI_CC_UNSPECIFIED_ERROR;
710 }
711
712 *data_len = dataInfo.size();
713 std::copy(dataInfo.begin(), dataInfo.end(), dataOut);
714 return IPMI_CC_OK;
715}
716
717ipmi_ret_t cmd_mdr2_send_data_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
718 ipmi_request_t request,
719 ipmi_response_t response,
720 ipmi_data_len_t data_len,
721 ipmi_context_t context)
722{
723 auto requestData =
724 reinterpret_cast<const MDRiiSendDataInfoRequest*>(request);
725 bool entryChanged = true;
726
727 if (*data_len != sizeof(MDRiiSendDataInfoRequest))
728 {
729 *data_len = 0;
730 return IPMI_CC_REQ_DATA_LEN_INVALID;
731 }
732
733 *data_len = 0;
734
735 if (requestData->dataLength > smbiosTableStorageSize)
736 {
737 phosphor::logging::log<phosphor::logging::level::ERR>(
738 "Requested data length is out of SMBIOS Table storage size.");
739 return IPMI_CC_PARM_OUT_OF_RANGE;
740 }
741
Vernon Mauery15419dd2019-05-24 09:40:30 -0700742 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
743 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700744
745 int agentIndex = agentLookup(requestData->agentId, service);
746 if (agentIndex == -1)
747 {
748 phosphor::logging::log<phosphor::logging::level::ERR>(
749 "Unknown agent id",
750 phosphor::logging::entry("ID=%x", requestData->agentId));
751 return IPMI_CC_PARM_OUT_OF_RANGE;
752 }
753
754 int idIndex =
755 findDataId(requestData->dataSetInfo.dataInfo,
756 sizeof(requestData->dataSetInfo.dataInfo), service);
757
758 if ((idIndex < 0) || (idIndex >= maxDirEntries))
759 {
760 phosphor::logging::log<phosphor::logging::level::ERR>(
761 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
762 return IPMI_CC_PARM_OUT_OF_RANGE;
763 }
764
Vernon Mauery15419dd2019-05-24 09:40:30 -0700765 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700766 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDataInfo");
767
768 method.append((uint8_t)idIndex, requestData->validFlag,
769 requestData->dataLength, requestData->dataVersion,
770 requestData->timeStamp);
771
Vernon Mauery15419dd2019-05-24 09:40:30 -0700772 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700773 if (reply.is_method_error())
774 {
775 phosphor::logging::log<phosphor::logging::level::ERR>(
776 "Error send data info",
777 phosphor::logging::entry("SERVICE=%s", service.c_str()),
778 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
779 return IPMI_CC_UNSPECIFIED_ERROR;
780 }
781 reply.read(entryChanged);
782
783 *data_len = 1;
784
785 if (entryChanged)
786 {
787 *(static_cast<uint8_t*>(response)) = 1;
788 }
789 else
790 {
791 *(static_cast<uint8_t*>(response)) = 0;
792 }
793
794 return IPMI_CC_OK;
795}
796
797ipmi_ret_t cmd_mdr2_data_start(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
798 ipmi_request_t request, ipmi_response_t response,
799 ipmi_data_len_t data_len, ipmi_context_t context)
800{
801 auto requestData = reinterpret_cast<const MDRiiDataStartRequest*>(request);
802 auto responseData = reinterpret_cast<MDRiiDataStartResponse*>(response);
803 std::vector<uint8_t> idVector;
804
805 if (*data_len != sizeof(MDRiiDataStartRequest))
806 {
807 *data_len = 0;
808 return IPMI_CC_REQ_DATA_LEN_INVALID;
809 }
810
811 *data_len = 0;
812
813 if (requestData->dataLength > smbiosTableStorageSize)
814 {
815 phosphor::logging::log<phosphor::logging::level::ERR>(
816 "Requested data length is out of SMBIOS Table storage size.");
817 return IPMI_CC_PARM_OUT_OF_RANGE;
818 }
819
820 if ((requestData->xferLength + requestData->xferAddress) > mdriiSMSize)
821 {
822 phosphor::logging::log<phosphor::logging::level::ERR>(
823 "Invalid data address and size");
824 return IPMI_CC_PARM_OUT_OF_RANGE;
825 }
826
Vernon Mauery15419dd2019-05-24 09:40:30 -0700827 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
828 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700829
830 int agentIndex = agentLookup(requestData->agentId, service);
831 if (agentIndex == -1)
832 {
833 phosphor::logging::log<phosphor::logging::level::ERR>(
834 "Unknown agent id",
835 phosphor::logging::entry("ID=%x", requestData->agentId));
836 return IPMI_CC_PARM_OUT_OF_RANGE;
837 }
838
839 int idIndex =
840 findDataId(requestData->dataSetInfo.dataInfo,
841 sizeof(requestData->dataSetInfo.dataInfo), service);
842
843 if ((idIndex < 0) || (idIndex >= maxDirEntries))
844 {
845 phosphor::logging::log<phosphor::logging::level::ERR>(
846 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
847 return IPMI_CC_PARM_OUT_OF_RANGE;
848 }
849
Vernon Mauery15419dd2019-05-24 09:40:30 -0700850 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700851 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "DataStart");
852
853 for (uint8_t infoIndex = 0; infoIndex < sizeof(DataIdStruct); infoIndex++)
854 {
855 idVector.push_back(requestData->dataSetInfo.dataInfo[infoIndex]);
856 }
857 method.append((uint8_t)idIndex, idVector, requestData->dataLength,
858 requestData->xferAddress, requestData->xferLength,
859 requestData->timeout);
860
Vernon Mauery15419dd2019-05-24 09:40:30 -0700861 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700862 if (reply.is_method_error())
863 {
864 int errNumber = reply.get_errno();
865 if (errNumber == ENOMEM)
866 {
867 phosphor::logging::log<phosphor::logging::level::ERR>(
868 "Send data start failed - cannot map share memory");
869 return IPMI_CC_UNSPECIFIED_ERROR;
870 }
871 else if (errNumber == EINVAL)
872 {
873 phosphor::logging::log<phosphor::logging::level::ERR>(
874 "Invalid data address and size");
875 return IPMI_CC_PARM_OUT_OF_RANGE;
876 }
877 else
878 {
879 phosphor::logging::log<phosphor::logging::level::ERR>(
880 "Error Send Data Start",
881 phosphor::logging::entry("SERVICE=%s", service.c_str()),
882 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
883 return IPMI_CC_UNSPECIFIED_ERROR;
884 }
885 }
886 uint8_t xferStartAck = 0;
887 uint16_t sessionHandle = 0;
888 reply.read(xferStartAck, sessionHandle);
889 responseData->sessionHandle = sessionHandle;
890 responseData->xferStartAck = xferStartAck;
891 if (responseData->xferStartAck == 0)
892 {
893 phosphor::logging::log<phosphor::logging::level::ERR>(
894 "Send data start unexpected error");
895 return IPMI_CC_UNSPECIFIED_ERROR;
896 }
897
898 *data_len = sizeof(MDRiiDataStartResponse);
899 return IPMI_CC_OK;
900}
901
902ipmi_ret_t cmd_mdr2_data_done(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
903 ipmi_request_t request, ipmi_response_t response,
904 ipmi_data_len_t data_len, ipmi_context_t context)
905{
906 auto requestData = reinterpret_cast<const MDRiiDataDoneRequest*>(request);
907 std::string resStatus;
908
909 if (*data_len != sizeof(MDRiiDataDoneRequest))
910 {
911 *data_len = 0;
912 return IPMI_CC_REQ_DATA_LEN_INVALID;
913 }
914
915 *data_len = 0;
916
Vernon Mauery15419dd2019-05-24 09:40:30 -0700917 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
918 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700919
920 int agentIndex = agentLookup(requestData->agentId, service);
921 if (agentIndex == -1)
922 {
923 phosphor::logging::log<phosphor::logging::level::ERR>(
924 "Unknown agent id",
925 phosphor::logging::entry("ID=%x", requestData->agentId));
926 return IPMI_CC_PARM_OUT_OF_RANGE;
927 }
928
929 int idIndex = findLockHandle(requestData->lockHandle, service);
930
931 if ((idIndex < 0) || (idIndex >= maxDirEntries))
932 {
933 phosphor::logging::log<phosphor::logging::level::ERR>(
934 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
935 return IPMI_CC_PARM_OUT_OF_RANGE;
936 }
937
Vernon Mauery15419dd2019-05-24 09:40:30 -0700938 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700939 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "DataDone");
940 method.append((uint8_t)idIndex);
941
Vernon Mauery15419dd2019-05-24 09:40:30 -0700942 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700943 if (reply.is_method_error())
944 {
945 if (reply.get_errno() == EBUSY)
946 {
947 phosphor::logging::log<phosphor::logging::level::ERR>(
948 "Send data done failed - cannot unlock idIndex");
949 return IPMI_CC_DESTINATION_UNAVAILABLE;
950 }
951 phosphor::logging::log<phosphor::logging::level::ERR>(
952 "Error Send Data done",
953 phosphor::logging::entry("SERVICE=%s", service.c_str()),
954 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
955 return IPMI_CC_UNSPECIFIED_ERROR;
956 }
957 reply.read(resStatus);
958
959 if (resStatus != "success")
960 {
961 phosphor::logging::log<phosphor::logging::level::ERR>(
962 "Data done failure.");
963 return IPMI_CC_DESTINATION_UNAVAILABLE;
964 }
965
966 return IPMI_CC_OK;
967}
968
969ipmi_ret_t cmd_mdr2_send_data_block(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
970 ipmi_request_t request,
971 ipmi_response_t response,
972 ipmi_data_len_t data_len,
973 ipmi_context_t context)
974{
975 auto requestData =
976 reinterpret_cast<const MDRiiSendDataBlockRequest*>(request);
977 std::string resStatus;
978
979 if (*data_len != sizeof(MDRiiSendDataBlockRequest))
980 {
981 *data_len = 0;
982 return IPMI_CC_REQ_DATA_LEN_INVALID;
983 }
984
985 *data_len = 0;
986
Vernon Mauery15419dd2019-05-24 09:40:30 -0700987 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
988 std::string service = ipmi::getService(*bus, MDRV2_INTERFACE, MDRV2_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700989
990 int agentIndex = agentLookup(requestData->agentId, service);
991 if (agentIndex == -1)
992 {
993 phosphor::logging::log<phosphor::logging::level::ERR>(
994 "Unknown agent id",
995 phosphor::logging::entry("ID=%x", requestData->agentId));
996 return IPMI_CC_PARM_OUT_OF_RANGE;
997 }
998
999 int idIndex = findLockHandle(requestData->lockHandle, service);
1000
1001 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1002 {
1003 phosphor::logging::log<phosphor::logging::level::ERR>(
1004 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
1005 return IPMI_CC_PARM_OUT_OF_RANGE;
1006 }
1007
Vernon Mauery15419dd2019-05-24 09:40:30 -07001008 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001009 service.c_str(), MDRV2_PATH, MDRV2_INTERFACE, "SendDataBlock");
1010 method.append((uint8_t)idIndex, requestData->xferOffset,
1011 requestData->xferLength, requestData->checksum);
1012
Vernon Mauery15419dd2019-05-24 09:40:30 -07001013 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001014 if (reply.is_method_error())
1015 {
1016 int errNumber = reply.get_errno();
1017 if (errNumber == EINVAL)
1018 {
1019 phosphor::logging::log<phosphor::logging::level::ERR>(
1020 "Send data block Invalid checksum");
1021 return IPMI_CC_OEM_INVALID_CHECKSUM;
1022 }
1023 else if (errNumber == ENOBUFS)
1024 {
1025 phosphor::logging::log<phosphor::logging::level::ERR>(
1026 "Send data block Invalid offset/length");
1027 return IPMI_CC_REQUEST_DATA_FIELD_LENGTH_LIMIT_EXCEEDED;
1028 }
1029 else if (errNumber == EBUSY)
1030 {
1031 phosphor::logging::log<phosphor::logging::level::ERR>(
1032 "Send data block failed, other data is updating");
1033 return IPMI_CC_DESTINATION_UNAVAILABLE;
1034 }
1035 else
1036 {
1037 phosphor::logging::log<phosphor::logging::level::ERR>(
1038 "Error Send data block",
1039 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1040 phosphor::logging::entry("PATH=%s", MDRV2_PATH));
1041 return IPMI_CC_UNSPECIFIED_ERROR;
1042 }
1043 }
1044 reply.read(resStatus);
1045
1046 if (resStatus != "success")
1047 {
1048 phosphor::logging::log<phosphor::logging::level::ERR>(
1049 "send data block failure.");
1050 return IPMI_CC_DESTINATION_UNAVAILABLE;
1051 }
1052
1053 return IPMI_CC_OK;
1054}
1055
1056static void register_netfn_smbiosmdrv2_functions(void)
1057{
1058 // MDR V2 Command
1059 // <Get MDRII Status Command>
1060 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1061 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_AGENT_STATUS,
1062 NULL, cmd_mdr2_agent_status, PRIVILEGE_OPERATOR);
1063
1064 // <Get MDRII Directory Command>
1065 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1066 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DIR, NULL,
1067 cmd_mdr2_get_dir, PRIVILEGE_OPERATOR);
1068
1069 // <Get MDRII Data Info Command>
1070 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1071 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_INFO,
1072 NULL, cmd_mdr2_get_data_info, PRIVILEGE_OPERATOR);
1073
1074 // <Lock MDRII Data Command>
1075 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1076 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_LOCK_DATA, NULL,
1077 cmd_mdr2_lock_data, PRIVILEGE_OPERATOR);
1078
1079 // <Unlock MDRII Data Command>
1080 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1081 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_UNLOCK_DATA,
1082 NULL, cmd_mdr2_unlock_data, PRIVILEGE_OPERATOR);
1083
1084 // <Get MDRII Data Block Command>
1085 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1086 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_BLOCK,
1087 NULL, cmd_mdr2_get_data_block, PRIVILEGE_OPERATOR);
1088
1089 // <Send MDRII Directory Command>
1090 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1091 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DIR, NULL,
1092 cmd_mdr2_send_dir, PRIVILEGE_OPERATOR);
1093
1094 // <Send MDRII Info Offer>
1095 ipmi_register_callback(
1096 NETFUN_INTEL_APP_OEM,
1097 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO_OFFER, NULL,
1098 cmd_mdr2_data_info_offer, PRIVILEGE_OPERATOR);
1099
1100 // <Send MDRII Data Info>
1101 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1102 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO,
1103 NULL, cmd_mdr2_send_data_info, PRIVILEGE_OPERATOR);
1104
1105 // <Send MDRII Data Start>
1106 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1107 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_START, NULL,
1108 cmd_mdr2_data_start, PRIVILEGE_OPERATOR);
1109
1110 // <Send MDRII Data Done>
1111 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1112 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_DONE, NULL,
1113 cmd_mdr2_data_done, PRIVILEGE_OPERATOR);
1114
1115 // <Send MDRII Data Block>
1116 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1117 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_BLOCK,
1118 NULL, cmd_mdr2_send_data_block, PRIVILEGE_OPERATOR);
1119}