blob: 5f3dd8427fb9d5dbd744d1be36c15d592903616e [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>
18#include <fcntl.h>
Vernon Mauerya3702c12019-05-22 13:20:59 -070019#include <limits.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <unistd.h>
23
24#include <commandutils.hpp>
25#include <cstdint>
26#include <fstream>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +000027#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070028#include <ipmid/utils.hpp>
29#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070030#include <sdbusplus/message/types.hpp>
31#include <smbiosmdrv2handler.hpp>
32#include <string>
33#include <vector>
34#include <xyz/openbmc_project/Common/error.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070035
36std::unique_ptr<MDRV2> mdrv2 = nullptr;
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +000037static constexpr const uint8_t ccOemInvalidChecksum = 0x85;
jayaprakash Mutyala40fec612019-06-19 11:53:03 +000038static constexpr size_t dataInfoSize = 16;
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +000039static constexpr const uint8_t ccStorageLeak = 0xC4;
Vernon Mauerya3702c12019-05-22 13:20:59 -070040
Vernon Mauerya3702c12019-05-22 13:20:59 -070041static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070042
43int MDRV2::agentLookup(const uint16_t &agentId)
44{
45 int agentIndex = -1;
46
47 if (lastAgentId == agentId)
48 {
49 return lastAgentIndex;
50 }
51
52 if (agentId == smbiosAgentId)
53 {
54 return firstAgentIndex;
55 }
56
57 return agentIndex;
58}
59
60int MDRV2::sdplusMdrv2GetProperty(const std::string &name,
61 sdbusplus::message::variant<uint8_t> &value,
62 const std::string &service)
63{
Vernon Mauery15419dd2019-05-24 09:40:30 -070064 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Vernon Mauerya3702c12019-05-22 13:20:59 -070065 sdbusplus::message::message method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070066 bus->new_method_call(service.c_str(), mdrv2Path, dbusProperties, "Get");
Vernon Mauerya3702c12019-05-22 13:20:59 -070067 method.append(mdrv2Interface, name);
68
Vernon Mauery15419dd2019-05-24 09:40:30 -070069 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070070
71 try
72 {
Vernon Mauery15419dd2019-05-24 09:40:30 -070073 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070074 reply.read(value);
75 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -070076 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -070077 {
78 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -070079 "Error get property, sdbusplus call failed",
80 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -070081 return -1;
82 }
83
84 return 0;
85}
86
87int MDRV2::syncDirCommonData(uint8_t idIndex, uint32_t size,
88 const std::string &service)
89{
90 std::vector<uint32_t> commonData;
Vernon Mauery15419dd2019-05-24 09:40:30 -070091 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Vernon Mauerya3702c12019-05-22 13:20:59 -070092 sdbusplus::message::message method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070093 bus->new_method_call(service.c_str(), mdrv2Path, mdrv2Interface,
94 "SynchronizeDirectoryCommonData");
Vernon Mauerya3702c12019-05-22 13:20:59 -070095 method.append(idIndex, size);
96
97 try
98 {
Vernon Mauery15419dd2019-05-24 09:40:30 -070099 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700100 reply.read(commonData);
101 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700102 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700103 {
104 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700105 "Error sync dir common data with service",
106 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700107 return -1;
108 }
109
110 if (commonData.size() < syncDirCommonSize)
111 {
112 phosphor::logging::log<phosphor::logging::level::ERR>(
113 "Error sync dir common data - data length invalid");
114 return -1;
115 }
116 smbiosDir.dir[idIndex].common.dataSetSize = commonData.at(0);
117 smbiosDir.dir[idIndex].common.dataVersion = commonData.at(1);
118 smbiosDir.dir[idIndex].common.timestamp = commonData.at(2);
119
120 return 0;
121}
122
123int MDRV2::findDataId(const uint8_t *dataInfo, const size_t &len,
124 const std::string &service)
125{
126 int idIndex = -1;
127
128 if (dataInfo == nullptr)
129 {
130 phosphor::logging::log<phosphor::logging::level::ERR>(
131 "Error dataInfo, input is null point");
132 return -1;
133 }
134
Vernon Mauery15419dd2019-05-24 09:40:30 -0700135 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
136 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700137 service.c_str(), mdrv2Path, mdrv2Interface, "FindIdIndex");
138 std::vector<uint8_t> info;
139 info.resize(len);
140 std::copy(dataInfo, dataInfo + len, info.data());
141 method.append(info);
142
143 try
144 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700145 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700146 reply.read(idIndex);
147 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700148 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700149 {
150 phosphor::logging::log<phosphor::logging::level::ERR>(
151 "Error find id index",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700152 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700153 phosphor::logging::entry("SERVICE=%s", service.c_str()),
154 phosphor::logging::entry("PATH=%s", mdrv2Path));
155 return -1;
156 }
157
158 return idIndex;
159}
160
161uint16_t MDRV2::getSessionHandle(Mdr2DirStruct *dir)
162{
163 if (dir == NULL)
164 {
165 phosphor::logging::log<phosphor::logging::level::ERR>(
166 "Empty dir point");
167 return 0;
168 }
169 dir->sessionHandle++;
170 if (dir->sessionHandle == 0)
171 {
172 dir->sessionHandle = 1;
173 }
174
175 return dir->sessionHandle;
176}
177
178int MDRV2::findLockHandle(const uint16_t &lockHandle)
179{
180 int idIndex = -1;
181
182 for (int index = 0; index < smbiosDir.dirEntries; index++)
183 {
184 if (lockHandle == smbiosDir.dir[index].lockHandle)
185 {
186 return index;
187 }
188 }
189
190 return idIndex;
191}
192
193bool MDRV2::smbiosIsUpdating(uint8_t index)
194{
195 if (index > maxDirEntries)
196 {
197 return false;
198 }
199 if (smbiosDir.dir[index].stage == MDR2SMBIOSStatusEnum::mdr2Updating)
200 {
201 return true;
202 }
203
204 return false;
205}
206
207uint32_t MDRV2::calcChecksum32(uint8_t *buf, uint32_t len)
208{
209 uint32_t sum = 0;
210
211 if (buf == nullptr)
212 {
213 return invalidChecksum;
214 }
215
216 for (uint32_t index = 0; index < len; index++)
217 {
218 sum += buf[index];
219 }
220
221 return sum;
222}
223
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000224/** @brief implements mdr2 agent status command
225 * @param agentId
226 * @param dirVersion
227 *
228 * @returns IPMI completion code plus response data
229 * - mdrVersion
230 * - agentVersion
231 * - dirVersion
232 * - dirEntries
233 * - dataRequest
234 */
235ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
236 mdr2AgentStatus(uint16_t agentId, uint8_t dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700237{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700238 if (mdrv2 == nullptr)
239 {
240 mdrv2 = std::make_unique<MDRV2>();
241 }
242
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000243 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700244 if (agentIndex == -1)
245 {
246 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000247 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
248 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700249 }
250
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000251 constexpr uint8_t mdrVersion = mdr2Version;
252 constexpr uint8_t agentVersion = smbiosAgentVersion;
253 uint8_t dirVersionResp = mdrv2->smbiosDir.dirVersion;
254 uint8_t dirEntries = mdrv2->smbiosDir.dirEntries;
255 uint8_t dataRequest;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700256
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000257 if (mdrv2->smbiosDir.remoteDirVersion != dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700258 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000259 mdrv2->smbiosDir.remoteDirVersion = dirVersion;
260 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700261 static_cast<uint8_t>(DirDataRequestEnum::dirDataRequested);
262 }
263 else
264 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000265 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700266 static_cast<uint8_t>(DirDataRequestEnum::dirDataNotRequested);
267 }
268
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000269 return ipmi::responseSuccess(mdrVersion, agentVersion, dirVersionResp,
270 dirEntries, dataRequest);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700271}
272
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000273/** @brief implements mdr2 get directory command
274 * @param agentId
275 * @param dirIndex
276 * @returns IPMI completion code plus response data
277 * - dataOut
278 */
279ipmi::RspType<std::vector<uint8_t>> mdr2GetDir(uint16_t agentId,
280 uint8_t dirIndex)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700281{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700282 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
283 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700284
285 if (mdrv2 == nullptr)
286 {
287 mdrv2 = std::make_unique<MDRV2>();
288 }
289
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000290 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700291 if (agentIndex == -1)
292 {
293 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000294 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
295 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700296 }
297
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000298 std::variant<uint8_t> value = 0;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700299 if (0 != mdrv2->sdplusMdrv2GetProperty("DirectoryEntries", value, service))
300 {
301 phosphor::logging::log<phosphor::logging::level::ERR>(
302 "Error getting DirEnries");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000303 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700304 }
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000305 if (dirIndex > std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700306 {
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000307 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700308 }
309
Vernon Mauery15419dd2019-05-24 09:40:30 -0700310 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700311 service.c_str(), mdrv2Path, mdrv2Interface, "GetDirectoryInformation");
312
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000313 method.append(dirIndex);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700314
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000315 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700316 try
317 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700318 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000319 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700320 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700321 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700322 {
323 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700324 "Error get dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700325 phosphor::logging::entry("SERVICE=%s", service.c_str()),
326 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000327 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700328 }
329
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000330 constexpr size_t getDirRespSize = 6;
331 if (dataOut.size() < getDirRespSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700332 {
333 phosphor::logging::log<phosphor::logging::level::ERR>(
334 "Error get dir, response length invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000335 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700336 }
337
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000338 if (dataOut.size() > MAX_IPMI_BUFFER) // length + completion code should no
339 // more than MAX_IPMI_BUFFER
Vernon Mauerya3702c12019-05-22 13:20:59 -0700340 {
341 phosphor::logging::log<phosphor::logging::level::ERR>(
342 "Data length send from service is invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000343 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700344 }
345
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000346 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700347}
348
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000349ipmi::RspType<bool> mdr2SendDir(uint16_t agentId, uint8_t dirVersion,
350 uint8_t dirIndex, uint8_t returnedEntries,
351 uint8_t remainingEntries,
352 std::array<uint8_t, 16> dataInfo, uint32_t size,
353 uint32_t dataSetSize, uint32_t dataVersion,
354 uint32_t timestamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700355{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700356 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
357 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700358
359 if (mdrv2 == nullptr)
360 {
361 mdrv2 = std::make_unique<MDRV2>();
362 }
363
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000364 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700365 if (agentIndex == -1)
366 {
367 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000368 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
369 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700370 }
371
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000372 if ((dirIndex + returnedEntries) > maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700373 {
374 phosphor::logging::log<phosphor::logging::level::ERR>(
375 "Too many directory entries");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000376 return ipmi::response(ccStorageLeak);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700377 }
378
Vernon Mauery15419dd2019-05-24 09:40:30 -0700379 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700380 service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000381 method.append(dirVersion, dirIndex, returnedEntries, remainingEntries,
382 dataInfo, size, dataSetSize, dataVersion, timestamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700383
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000384 bool terminate = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385 try
386 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700387 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000388 reply.read(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700389 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700390 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700391 {
392 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700393 "Error send dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700394 phosphor::logging::entry("SERVICE=%s", service.c_str()),
395 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000396 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700397 }
398
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000399 return ipmi::responseSuccess(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700400}
401
402ipmi_ret_t cmd_mdr2_get_data_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
403 ipmi_request_t request,
404 ipmi_response_t response,
405 ipmi_data_len_t data_len,
406 ipmi_context_t context)
407{
408 auto requestData =
409 reinterpret_cast<const MDRiiGetDataInfoRequest *>(request);
410 auto dataOut = reinterpret_cast<uint8_t *>(response);
411 std::vector<uint8_t> res;
412
413 if (*data_len < sizeof(MDRiiGetDataInfoRequest))
414 {
415 *data_len = 0;
416 return IPMI_CC_REQ_DATA_LEN_INVALID;
417 }
418
419 *data_len = 0;
420
Vernon Mauery15419dd2019-05-24 09:40:30 -0700421 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
422 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700423
424 if (mdrv2 == nullptr)
425 {
426 mdrv2 = std::make_unique<MDRV2>();
427 }
428
429 int agentIndex = mdrv2->agentLookup(requestData->agentId);
430 if (agentIndex == -1)
431 {
432 phosphor::logging::log<phosphor::logging::level::ERR>(
433 "Unknown agent id",
434 phosphor::logging::entry("ID=%x", requestData->agentId));
435 return IPMI_CC_PARM_OUT_OF_RANGE;
436 }
437
438 int idIndex =
439 mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
440 sizeof(requestData->dataSetInfo.dataInfo), service);
441
442 if ((idIndex < 0) || (idIndex >= maxDirEntries))
443 {
444 phosphor::logging::log<phosphor::logging::level::ERR>(
445 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
446 return IPMI_CC_PARM_OUT_OF_RANGE;
447 }
448
Vernon Mauery15419dd2019-05-24 09:40:30 -0700449 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700450 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
451
452 method.append(idIndex);
453
454 try
455 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700456 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700457 reply.read(res);
458 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700459 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700460 {
461 phosphor::logging::log<phosphor::logging::level::ERR>(
462 "Error get data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700463 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700464 phosphor::logging::entry("SERVICE=%s", service.c_str()),
465 phosphor::logging::entry("PATH=%s", mdrv2Path));
466 return IPMI_CC_RESPONSE_ERROR;
467 }
468
469 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
470 {
471 phosphor::logging::log<phosphor::logging::level::ERR>(
472 "Get data info response length not invalid");
473 return IPMI_CC_UNSPECIFIED_ERROR;
474 }
475 *data_len = static_cast<size_t>(res.size());
476 std::copy(&res[0], &res[*data_len], dataOut);
477
478 return IPMI_CC_OK;
479}
480
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000481/** @brief implements mdr2 data info offer command
482 * @param agentId - Offer a agent ID to get the "Data Set ID"
483 *
484 * @returns IPMI completion code plus response data
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000485 * - dataOut - data Set Id
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000486 */
487ipmi::RspType<std::vector<uint8_t>> mdr2DataInfoOffer(uint16_t agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700488{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700489 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
490 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700491
492 if (mdrv2 == nullptr)
493 {
494 mdrv2 = std::make_unique<MDRV2>();
495 }
496
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000497 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700498 if (agentIndex == -1)
499 {
500 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000501 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
502 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700503 }
504
Vernon Mauery15419dd2019-05-24 09:40:30 -0700505 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700506 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
507
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000508 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700509 try
510 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700511 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000512 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700513 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700514 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700515 {
516 phosphor::logging::log<phosphor::logging::level::ERR>(
517 "Error send data info offer",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700518 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700519 phosphor::logging::entry("SERVICE=%s", service.c_str()),
520 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000521 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700522 }
523
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000524 constexpr size_t respInfoSize = 16;
525 if (dataOut.size() != respInfoSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700526 {
527 phosphor::logging::log<phosphor::logging::level::ERR>(
528 "Error send data info offer, return length invalid");
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000529 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700530 }
531
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000532 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700533}
534
535ipmi_ret_t cmd_mdr2_send_data_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
536 ipmi_request_t request,
537 ipmi_response_t response,
538 ipmi_data_len_t data_len,
539 ipmi_context_t context)
540{
541 auto requestData =
542 reinterpret_cast<const MDRiiSendDataInfoRequest *>(request);
543 bool entryChanged = true;
544
545 if (*data_len != sizeof(MDRiiSendDataInfoRequest))
546 {
547 *data_len = 0;
548 return IPMI_CC_REQ_DATA_LEN_INVALID;
549 }
550
551 *data_len = 0;
552
553 if (requestData->dataLength > smbiosTableStorageSize)
554 {
555 phosphor::logging::log<phosphor::logging::level::ERR>(
556 "Requested data length is out of SMBIOS Table storage size.");
557 return IPMI_CC_PARM_OUT_OF_RANGE;
558 }
559
Vernon Mauery15419dd2019-05-24 09:40:30 -0700560 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
561 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700562
563 if (mdrv2 == nullptr)
564 {
565 mdrv2 = std::make_unique<MDRV2>();
566 }
567
568 int agentIndex = mdrv2->agentLookup(requestData->agentId);
569 if (agentIndex == -1)
570 {
571 phosphor::logging::log<phosphor::logging::level::ERR>(
572 "Unknown agent id",
573 phosphor::logging::entry("ID=%x", requestData->agentId));
574 return IPMI_CC_PARM_OUT_OF_RANGE;
575 }
576
577 int idIndex =
578 mdrv2->findDataId(requestData->dataSetInfo.dataInfo,
579 sizeof(requestData->dataSetInfo.dataInfo), service);
580
581 if ((idIndex < 0) || (idIndex >= maxDirEntries))
582 {
583 phosphor::logging::log<phosphor::logging::level::ERR>(
584 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
585 return IPMI_CC_PARM_OUT_OF_RANGE;
586 }
587
Vernon Mauery15419dd2019-05-24 09:40:30 -0700588 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700589 service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
590
591 method.append((uint8_t)idIndex, requestData->validFlag,
592 requestData->dataLength, requestData->dataVersion,
593 requestData->timeStamp);
594
595 try
596 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700597 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700598 reply.read(entryChanged);
599 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700600 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700601 {
602 phosphor::logging::log<phosphor::logging::level::ERR>(
603 "Error send data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700604 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700605 phosphor::logging::entry("SERVICE=%s", service.c_str()),
606 phosphor::logging::entry("PATH=%s", mdrv2Path));
607 return IPMI_CC_RESPONSE_ERROR;
608 }
609
610 *data_len = 1;
611
612 if (entryChanged)
613 {
614 *(static_cast<uint8_t *>(response)) = 1;
615 }
616 else
617 {
618 *(static_cast<uint8_t *>(response)) = 0;
619 }
620
621 return IPMI_CC_OK;
622}
623
624ipmi_ret_t cmd_mdr2_get_data_block(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
625 ipmi_request_t request,
626 ipmi_response_t response,
627 ipmi_data_len_t data_len,
628 ipmi_context_t context)
629{
630 auto requestData =
631 reinterpret_cast<const MDRiiGetDataBlockRequest *>(request);
632 auto responseData = reinterpret_cast<MDRiiGetDataBlockResponse *>(response);
633 std::tuple<uint8_t, uint32_t, uint32_t, std::vector<uint8_t>> res;
634 std::vector<uint8_t> resData;
635 uint8_t status = 1;
636
637 if (*data_len != sizeof(MDRiiGetDataBlockRequest))
638 {
639 *data_len = 0;
640 return IPMI_CC_REQ_DATA_LEN_INVALID;
641 }
642
643 *data_len = 0;
644
Vernon Mauerya3702c12019-05-22 13:20:59 -0700645 if (mdrv2 == nullptr)
646 {
647 mdrv2 = std::make_unique<MDRV2>();
648 }
649
650 int agentIndex = mdrv2->agentLookup(requestData->agentId);
651 if (agentIndex == -1)
652 {
653 phosphor::logging::log<phosphor::logging::level::ERR>(
654 "Unknown agent id",
655 phosphor::logging::entry("ID=%x", requestData->agentId));
656 return IPMI_CC_PARM_OUT_OF_RANGE;
657 }
658
659 int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
660
661 if ((idIndex < 0) || (idIndex >= maxDirEntries))
662 {
663 phosphor::logging::log<phosphor::logging::level::ERR>(
664 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
665 return IPMI_CC_PARM_OUT_OF_RANGE;
666 }
667
668 if (requestData->xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
669 {
670 phosphor::logging::log<phosphor::logging::level::ERR>(
671 "Offset is outside of range.");
672 return IPMI_CC_PARM_OUT_OF_RANGE;
673 }
674
675 size_t outSize =
676 (requestData->xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
677 ? mdrv2->smbiosDir.dir[idIndex].xferSize
678 : requestData->xferLength;
679 if (outSize > UINT_MAX - requestData->xferOffset)
680 {
681 phosphor::logging::log<phosphor::logging::level::ERR>(
682 "Out size and offset are out of range");
683 return IPMI_CC_PARM_OUT_OF_RANGE;
684 }
685 if ((requestData->xferOffset + outSize) >
686 mdrv2->smbiosDir.dir[idIndex].common.size)
687 {
688 outSize =
689 mdrv2->smbiosDir.dir[idIndex].common.size - requestData->xferOffset;
690 }
691
692 responseData->xferLength = outSize;
693 if (responseData->xferLength > requestData->xferLength)
694 {
695 phosphor::logging::log<phosphor::logging::level::ERR>(
696 "Get data block unexpected error.");
697 return IPMI_CC_UNSPECIFIED_ERROR;
698 }
699
700 if ((requestData->xferOffset + outSize) >
701 UINT_MAX -
702 reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
703 {
704 phosphor::logging::log<phosphor::logging::level::ERR>(
705 "Input data to calculate checksum is out of range");
706 return IPMI_CC_PARM_OUT_OF_RANGE;
707 }
708
709 uint32_t u32Checksum = mdrv2->calcChecksum32(
710 mdrv2->smbiosDir.dir[idIndex].dataStorage + requestData->xferOffset,
711 outSize);
712 if (u32Checksum == invalidChecksum)
713 {
714 phosphor::logging::log<phosphor::logging::level::ERR>(
715 "Get data block failed - invalid checksum");
716 return IPMI_CC_OEM_INVALID_CHECKSUM;
717 }
718 responseData->checksum = u32Checksum;
719
720 *data_len = sizeof(responseData->xferLength) +
721 sizeof(responseData->checksum) + outSize;
722
723 if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
724 // than MAX_IPMI_BUFFER
725 {
726 phosphor::logging::log<phosphor::logging::level::ERR>(
727 "Data length send from service is invalid");
728 *data_len = 0;
729 return IPMI_CC_RESPONSE_ERROR;
730 }
731
732 std::copy(
733 &mdrv2->smbiosDir.dir[idIndex].dataStorage[requestData->xferOffset],
734 &mdrv2->smbiosDir.dir[idIndex]
735 .dataStorage[requestData->xferOffset + outSize],
736 responseData->data);
737
738 return IPMI_CC_OK;
739}
740
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000741/** @brief implements mdr2 send data block command
742 * @param agentId
743 * @param lockHandle
744 * @param xferOffset
745 * @param xferLength
746 * @param checksum
747 *
748 * @returns IPMI completion code
749 */
750ipmi::RspType<> mdr2SendDataBlock(uint16_t agentId, uint16_t lockHandle,
751 uint32_t xferOffset, uint32_t xferLength,
752 uint32_t checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700753{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700754 if (mdrv2 == nullptr)
755 {
756 mdrv2 = std::make_unique<MDRV2>();
757 }
758
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000759 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700760 if (agentIndex == -1)
761 {
762 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000763 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
764 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700765 }
766
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000767 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700768
769 if ((idIndex < 0) || (idIndex >= maxDirEntries))
770 {
771 phosphor::logging::log<phosphor::logging::level::ERR>(
772 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000773 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700774 }
775
776 if (mdrv2->smbiosIsUpdating(idIndex))
777 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000778 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700779 {
780 phosphor::logging::log<phosphor::logging::level::ERR>(
781 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000782 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700783 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000784 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700785 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000786 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700787 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
788 {
789 phosphor::logging::log<phosphor::logging::level::ERR>(
790 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000791 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700792 }
793 if (reinterpret_cast<size_t>(
794 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000795 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700796 {
797 phosphor::logging::log<phosphor::logging::level::ERR>(
798 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000799 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700800 }
801 uint8_t *destAddr =
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000802 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700803 uint8_t *sourceAddr = reinterpret_cast<uint8_t *>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000804 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
805 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700806 {
807 phosphor::logging::log<phosphor::logging::level::ERR>(
808 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000809 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700810 }
811 else
812 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000813 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700814 {
815 phosphor::logging::log<phosphor::logging::level::ERR>(
816 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000817 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700818 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000819 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700820 }
821 }
822 else
823 {
824 phosphor::logging::log<phosphor::logging::level::ERR>(
825 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000826 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700827 }
828
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000829 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700830}
831
832bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data)
833{
834 std::ofstream smbiosFile(mdrType2File,
835 std::ios_base::binary | std::ios_base::trunc);
836 if (!smbiosFile.good())
837 {
838 phosphor::logging::log<phosphor::logging::level::ERR>(
839 "Write data from flash error - Open MDRV2 table file failure");
840 return false;
841 }
842
843 try
844 {
845 smbiosFile.write(reinterpret_cast<char *>(mdrHdr),
846 sizeof(MDRSMBIOSHeader));
847 smbiosFile.write(reinterpret_cast<char *>(data), mdrHdr->dataSize);
848 }
849 catch (std::ofstream::failure &e)
850 {
851 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700852 "Write data from flash error - write data error",
853 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700854 return false;
855 }
856
857 return true;
858}
859
860void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
861{
862 int memDriver = 0;
863
864 // open mem driver for the system memory access
865 memDriver = open("/dev/vgasharedmem", O_RDONLY);
866 if (memDriver < 0)
867 {
868 phosphor::logging::log<phosphor::logging::level::ERR>(
869 "Cannot access mem driver");
870 throw std::system_error(EIO, std::generic_category());
871 }
872
873 // map the system memory
874 vPtr = mmap(NULL, // where to map to: don't mind
875 areaSize, // how many bytes ?
876 PROT_READ, // want to read and write
877 MAP_SHARED, // no copy on write
878 memDriver, // handle to /dev/mem
879 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
880
881 close(memDriver);
882 if (vPtr == MAP_FAILED)
883 {
884 phosphor::logging::log<phosphor::logging::level::ERR>(
885 "Failed to map share memory");
886 throw std::system_error(EIO, std::generic_category());
887 }
888 size = areaSize;
889 physicalAddr = addr;
890}
891
892bool MDRV2::smbiosUnlock(uint8_t index)
893{
894 bool ret;
895 switch (smbiosDir.dir[index].stage)
896 {
897 case MDR2SMBIOSStatusEnum::mdr2Updating:
898 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
899 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
900
901 timer->stop();
902 smbiosDir.dir[index].lockHandle = 0;
903 ret = true;
904 break;
905
906 case MDR2SMBIOSStatusEnum::mdr2Updated:
907 case MDR2SMBIOSStatusEnum::mdr2Loaded:
908 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
909
910 timer->stop();
911
912 smbiosDir.dir[index].lockHandle = 0;
913 ret = true;
914 break;
915
916 default:
917 break;
918 }
919
920 return ret;
921}
922
923bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
924 uint16_t timeout)
925{
926 bool ret = false;
927 uint32_t u32Status = 0;
928
929 if (timeout == 0)
930 {
931 timeout = defaultTimeout;
932 }
933 std::chrono::microseconds usec(timeout * sysClock);
934
935 switch (smbiosDir.dir[index].stage)
936 {
937 case MDR2SMBIOSStatusEnum::mdr2Updating:
938 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
939 {
940 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
941 timer->start(usec);
942 lockIndex = index;
943
944 *session = getSessionHandle(&smbiosDir);
945 smbiosDir.dir[index].lockHandle = *session;
946 ret = true;
947 }
948 break;
949 case MDR2SMBIOSStatusEnum::mdr2Init:
950 if (flag)
951 {
952 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
953 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
954 timer->start(usec);
955 lockIndex = index;
956
957 *session = getSessionHandle(&smbiosDir);
958 smbiosDir.dir[index].lockHandle = *session;
959 ret = true;
960 }
961 break;
962
963 case MDR2SMBIOSStatusEnum::mdr2Updated:
964 case MDR2SMBIOSStatusEnum::mdr2Loaded:
965 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
966 {
967 if (flag)
968 {
969 smbiosDir.dir[index].stage =
970 MDR2SMBIOSStatusEnum::mdr2Updating;
971 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
972 }
973 else
974 {
975 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
976 }
977
978 timer->start(usec);
979 lockIndex = index;
980
981 *session = getSessionHandle(&smbiosDir);
982 smbiosDir.dir[index].lockHandle = *session;
983 ret = true;
984 }
985 break;
986
987 default:
988 break;
989 }
990 return ret;
991}
992
993void MDRV2::timeoutHandler()
994{
995 smbiosUnlock(lockIndex);
996 mdrv2->area.reset(nullptr);
997}
998
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000999/** @brief implements mdr2 lock data command
1000 * @param agentId
1001 * @param dataInfo
1002 * @param timeout
1003 *
1004 * @returns IPMI completion code plus response data
1005 * - mdr2Version
1006 * - session
1007 * - dataLength
1008 * - xferAddress
1009 * - xferLength
1010 */
1011ipmi::RspType<uint8_t, // mdr2Version
1012 uint16_t, // session
1013 uint32_t, // dataLength
1014 uint32_t, // xferAddress
1015 uint32_t // xferLength
1016 >
1017 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
1018 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001019{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001020 if (mdrv2 == nullptr)
1021 {
1022 mdrv2 = std::make_unique<MDRV2>();
1023 }
1024
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001025 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001026 if (agentIndex == -1)
1027 {
1028 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001029 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1030 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001031 }
1032
Vernon Mauery15419dd2019-05-24 09:40:30 -07001033 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1034 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001035
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001036 int idIndex = mdrv2->findDataId(dataInfo.data(), sizeof(dataInfo), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001037
1038 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1039 {
1040 phosphor::logging::log<phosphor::logging::level::ERR>(
1041 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001042 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001043 }
1044
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001045 uint16_t session = 0;
1046 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001047 {
1048 phosphor::logging::log<phosphor::logging::level::ERR>(
1049 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001050 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001051 }
1052
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001053 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1054 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1055 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001056
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001057 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1058 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001059}
1060
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001061/** @brief implements mdr2 unlock data command
1062 * @param agentId
1063 * @param lockHandle
1064 *
1065 * @returns IPMI completion code
1066 */
1067ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001068{
1069 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001070
Vernon Mauerya3702c12019-05-22 13:20:59 -07001071 if (mdrv2 == nullptr)
1072 {
1073 mdrv2 = std::make_unique<MDRV2>();
1074 }
1075
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001076 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001077 if (agentIndex == -1)
1078 {
1079 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001080 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1081 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001082 }
1083
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001084 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001085
1086 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1087 {
1088 phosphor::logging::log<phosphor::logging::level::ERR>(
1089 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001090 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001091 }
1092
1093 if (!mdrv2->smbiosUnlock(idIndex))
1094 {
1095 phosphor::logging::log<phosphor::logging::level::ERR>(
1096 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001097 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001098 }
1099
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001100 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001101}
1102
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001103/**
1104@brief This command is executed after POST BIOS to get the session info.
1105
1106@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1107
1108@return xferStartAck and session on success.
1109**/
1110ipmi::RspType<uint8_t, uint16_t>
1111 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1112 uint32_t dataLength, uint32_t xferAddress,
1113 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001114{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001115 uint16_t session = 0;
1116
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001117 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001118 {
1119 phosphor::logging::log<phosphor::logging::level::ERR>(
1120 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001121 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001122 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001123 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001124 {
1125 phosphor::logging::log<phosphor::logging::level::ERR>(
1126 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001127 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001128 }
1129
Vernon Mauery15419dd2019-05-24 09:40:30 -07001130 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1131 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001132
1133 if (mdrv2 == nullptr)
1134 {
1135 mdrv2 = std::make_unique<MDRV2>();
1136 }
1137
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001138 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001139 if (agentIndex == -1)
1140 {
1141 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001142 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1143 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001144 }
1145
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001146 int idIndex = mdrv2->findDataId(dataInfo.data(), sizeof(dataInfo), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001147
1148 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1149 {
1150 phosphor::logging::log<phosphor::logging::level::ERR>(
1151 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001152 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001153 }
1154
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001155 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001156 {
1157 try
1158 {
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001159 mdrv2->area =
1160 std::make_unique<SharedMemoryArea>(xferAddress, xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001161 }
1162 catch (const std::system_error &e)
1163 {
1164 mdrv2->smbiosUnlock(idIndex);
1165 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001166 "Unable to access share memory",
1167 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001168 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001169 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001170 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001171 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1172 if (-1 ==
1173 mdrv2->syncDirCommonData(
1174 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1175 {
1176 phosphor::logging::log<phosphor::logging::level::ERR>(
1177 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001178 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001179 }
1180 }
1181 else
1182 {
1183 phosphor::logging::log<phosphor::logging::level::ERR>(
1184 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001185 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001186 }
1187
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001188 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001189
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001190 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001191}
1192
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001193/**
1194@brief This command is executed to close the session.
1195
1196@param - agentId, lockHandle.
1197
1198@return completion code on success.
1199**/
1200ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001201{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001202
1203 if (mdrv2 == nullptr)
1204 {
1205 mdrv2 = std::make_unique<MDRV2>();
1206 }
1207
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001208 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001209 if (agentIndex == -1)
1210 {
1211 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001212 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1213 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001214 }
1215
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001216 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001217
1218 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1219 {
1220 phosphor::logging::log<phosphor::logging::level::ERR>(
1221 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001222 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001223 }
1224
1225 if (!mdrv2->smbiosUnlock(idIndex))
1226 {
1227 phosphor::logging::log<phosphor::logging::level::ERR>(
1228 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001229 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001230 }
1231
1232 mdrv2->area.reset(nullptr);
1233 MDRSMBIOSHeader mdr2Smbios;
1234 mdr2Smbios.mdrType = mdrTypeII;
1235 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1236 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1237 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1238
1239 if (access(smbiosPath, 0) == -1)
1240 {
1241 int flag = mkdir(smbiosPath, S_IRWXU);
1242 if (flag != 0)
1243 {
1244 phosphor::logging::log<phosphor::logging::level::ERR>(
1245 "create folder failed for writting smbios file");
1246 }
1247 }
1248 if (!mdrv2->storeDatatoFlash(
1249 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1250 {
1251 phosphor::logging::log<phosphor::logging::level::ERR>(
1252 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001253 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001254 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001255 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001256 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1257 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
1258 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001259 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1260
1261 try
1262 {
Vernon Mauery15419dd2019-05-24 09:40:30 -07001263 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001264 reply.read(status);
1265 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001266 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001267 {
1268 phosphor::logging::log<phosphor::logging::level::ERR>(
1269 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001270 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001271 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1272 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001273 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001274 }
1275
1276 if (!status)
1277 {
1278 phosphor::logging::log<phosphor::logging::level::ERR>(
1279 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001280 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001281 }
1282
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001283 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001284}
1285
1286static void register_netfn_smbiosmdrv2_functions(void)
1287{
1288 // MDR V2 Command
1289 // <Get MDRII Status Command>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001290 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1291 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_AGENT_STATUS,
1292 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001293
1294 // <Get MDRII Directory Command>
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001295 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1296 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DIR,
1297 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001298
1299 // <Send MDRII Directory Command>
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001300 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1301 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DIR,
1302 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001303
1304 // <Get MDRII Data Info Command>
1305 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1306 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_INFO,
1307 NULL, cmd_mdr2_get_data_info, PRIVILEGE_OPERATOR);
1308
1309 // <Send MDRII Info Offer>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001310 ipmi::registerHandler(
1311 ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1312 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO_OFFER,
1313 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001314
1315 // <Send MDRII Data Info>
1316 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1317 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO,
1318 NULL, cmd_mdr2_send_data_info, PRIVILEGE_OPERATOR);
1319
1320 // <Get MDRII Data Block Command>
1321 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1322 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_BLOCK,
1323 NULL, cmd_mdr2_get_data_block, PRIVILEGE_OPERATOR);
1324
1325 // <Send MDRII Data Block>
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001326 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1327 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_BLOCK,
1328 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001329
1330 // <Lock MDRII Data Command>
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001331 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1332 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_LOCK_DATA,
1333 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001334
1335 // <Unlock MDRII Data Command>
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001336 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1337 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_UNLOCK_DATA,
1338 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001339
1340 // <Send MDRII Data Start>
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001341 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1342 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_START,
1343 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001344
1345 // <Send MDRII Data Done>
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001346 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1347 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_DONE,
1348 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001349}