blob: d3c862ec8a5c9dfe2b2685bc1fc2c064d672c80c [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>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +000025#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070026#include <ipmid/utils.hpp>
Vernon Mauery98bbf692019-09-16 11:14:59 -070027#include <oemcommands.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070028#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070029#include <sdbusplus/message/types.hpp>
30#include <smbiosmdrv2handler.hpp>
James Feistfcd2d3a2020-05-28 10:38:15 -070031#include <xyz/openbmc_project/Common/error.hpp>
32
33#include <cstdint>
34#include <fstream>
Vernon Mauerya3702c12019-05-22 13:20:59 -070035#include <string>
36#include <vector>
Vernon Mauerya3702c12019-05-22 13:20:59 -070037
38std::unique_ptr<MDRV2> mdrv2 = nullptr;
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +000039static constexpr const uint8_t ccOemInvalidChecksum = 0x85;
jayaprakash Mutyala40fec612019-06-19 11:53:03 +000040static constexpr size_t dataInfoSize = 16;
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +000041static constexpr const uint8_t ccStorageLeak = 0xC4;
Vernon Mauerya3702c12019-05-22 13:20:59 -070042
Vernon Mauerya3702c12019-05-22 13:20:59 -070043static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070044
James Feistfcd2d3a2020-05-28 10:38:15 -070045int MDRV2::agentLookup(const uint16_t& agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -070046{
47 int agentIndex = -1;
48
49 if (lastAgentId == agentId)
50 {
51 return lastAgentIndex;
52 }
53
54 if (agentId == smbiosAgentId)
55 {
56 return firstAgentIndex;
57 }
58
59 return agentIndex;
60}
61
James Feistfcd2d3a2020-05-28 10:38:15 -070062int MDRV2::sdplusMdrv2GetProperty(const std::string& name,
Jason M. Bills0748c692022-09-08 15:34:08 -070063 ipmi::DbusVariant& value,
James Feistfcd2d3a2020-05-28 10:38:15 -070064 const std::string& service)
Vernon Mauerya3702c12019-05-22 13:20:59 -070065{
Vernon Mauery15419dd2019-05-24 09:40:30 -070066 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Patrick Williamsf944d2e2022-07-22 19:26:52 -050067 sdbusplus::message_t method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070068 bus->new_method_call(service.c_str(), mdrv2Path, dbusProperties, "Get");
Vernon Mauerya3702c12019-05-22 13:20:59 -070069 method.append(mdrv2Interface, name);
70
Patrick Williamsf944d2e2022-07-22 19:26:52 -050071 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070072
73 try
74 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -050075 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070076 reply.read(value);
77 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -050078 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -070079 {
80 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -070081 "Error get property, sdbusplus call failed",
82 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -070083 return -1;
84 }
85
86 return 0;
87}
88
89int MDRV2::syncDirCommonData(uint8_t idIndex, uint32_t size,
James Feistfcd2d3a2020-05-28 10:38:15 -070090 const std::string& service)
Vernon Mauerya3702c12019-05-22 13:20:59 -070091{
92 std::vector<uint32_t> commonData;
Vernon Mauery15419dd2019-05-24 09:40:30 -070093 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Patrick Williamsf944d2e2022-07-22 19:26:52 -050094 sdbusplus::message_t method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070095 bus->new_method_call(service.c_str(), mdrv2Path, mdrv2Interface,
96 "SynchronizeDirectoryCommonData");
Vernon Mauerya3702c12019-05-22 13:20:59 -070097 method.append(idIndex, size);
98
99 try
100 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500101 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700102 reply.read(commonData);
103 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500104 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700105 {
106 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700107 "Error sync dir common data with service",
108 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700109 return -1;
110 }
111
112 if (commonData.size() < syncDirCommonSize)
113 {
114 phosphor::logging::log<phosphor::logging::level::ERR>(
115 "Error sync dir common data - data length invalid");
116 return -1;
117 }
118 smbiosDir.dir[idIndex].common.dataSetSize = commonData.at(0);
119 smbiosDir.dir[idIndex].common.dataVersion = commonData.at(1);
120 smbiosDir.dir[idIndex].common.timestamp = commonData.at(2);
121
122 return 0;
123}
124
James Feistfcd2d3a2020-05-28 10:38:15 -0700125int MDRV2::findDataId(const uint8_t* dataInfo, const size_t& len,
126 const std::string& service)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700127{
128 int idIndex = -1;
129
130 if (dataInfo == nullptr)
131 {
132 phosphor::logging::log<phosphor::logging::level::ERR>(
133 "Error dataInfo, input is null point");
134 return -1;
135 }
136
Vernon Mauery15419dd2019-05-24 09:40:30 -0700137 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500138 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700139 service.c_str(), mdrv2Path, mdrv2Interface, "FindIdIndex");
140 std::vector<uint8_t> info;
141 info.resize(len);
142 std::copy(dataInfo, dataInfo + len, info.data());
143 method.append(info);
144
145 try
146 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500147 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700148 reply.read(idIndex);
149 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500150 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700151 {
152 phosphor::logging::log<phosphor::logging::level::ERR>(
153 "Error find id index",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700154 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700155 phosphor::logging::entry("SERVICE=%s", service.c_str()),
156 phosphor::logging::entry("PATH=%s", mdrv2Path));
157 return -1;
158 }
159
160 return idIndex;
161}
162
James Feistfcd2d3a2020-05-28 10:38:15 -0700163uint16_t MDRV2::getSessionHandle(Mdr2DirStruct* dir)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700164{
165 if (dir == NULL)
166 {
167 phosphor::logging::log<phosphor::logging::level::ERR>(
168 "Empty dir point");
169 return 0;
170 }
171 dir->sessionHandle++;
172 if (dir->sessionHandle == 0)
173 {
174 dir->sessionHandle = 1;
175 }
176
177 return dir->sessionHandle;
178}
179
James Feistfcd2d3a2020-05-28 10:38:15 -0700180int MDRV2::findLockHandle(const uint16_t& lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700181{
182 int idIndex = -1;
183
184 for (int index = 0; index < smbiosDir.dirEntries; index++)
185 {
186 if (lockHandle == smbiosDir.dir[index].lockHandle)
187 {
188 return index;
189 }
190 }
191
192 return idIndex;
193}
194
195bool MDRV2::smbiosIsUpdating(uint8_t index)
196{
P Dheeraj Srujan Kumar9f8d0272021-07-14 19:13:49 +0530197 if (index >= maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700198 {
199 return false;
200 }
201 if (smbiosDir.dir[index].stage == MDR2SMBIOSStatusEnum::mdr2Updating)
202 {
203 return true;
204 }
205
206 return false;
207}
208
James Feistfcd2d3a2020-05-28 10:38:15 -0700209uint32_t MDRV2::calcChecksum32(uint8_t* buf, uint32_t len)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700210{
211 uint32_t sum = 0;
212
213 if (buf == nullptr)
214 {
215 return invalidChecksum;
216 }
217
218 for (uint32_t index = 0; index < len; index++)
219 {
220 sum += buf[index];
221 }
222
223 return sum;
224}
225
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000226/** @brief implements mdr2 agent status command
227 * @param agentId
228 * @param dirVersion
229 *
230 * @returns IPMI completion code plus response data
231 * - mdrVersion
232 * - agentVersion
233 * - dirVersion
234 * - dirEntries
235 * - dataRequest
236 */
237ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
238 mdr2AgentStatus(uint16_t agentId, uint8_t dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700239{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700240 if (mdrv2 == nullptr)
241 {
242 mdrv2 = std::make_unique<MDRV2>();
243 }
244
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000245 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700246 if (agentIndex == -1)
247 {
248 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000249 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
250 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700251 }
252
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000253 constexpr uint8_t mdrVersion = mdr2Version;
254 constexpr uint8_t agentVersion = smbiosAgentVersion;
255 uint8_t dirVersionResp = mdrv2->smbiosDir.dirVersion;
256 uint8_t dirEntries = mdrv2->smbiosDir.dirEntries;
257 uint8_t dataRequest;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700258
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000259 if (mdrv2->smbiosDir.remoteDirVersion != dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700260 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000261 mdrv2->smbiosDir.remoteDirVersion = dirVersion;
262 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700263 static_cast<uint8_t>(DirDataRequestEnum::dirDataRequested);
264 }
265 else
266 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000267 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700268 static_cast<uint8_t>(DirDataRequestEnum::dirDataNotRequested);
269 }
270
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000271 return ipmi::responseSuccess(mdrVersion, agentVersion, dirVersionResp,
272 dirEntries, dataRequest);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700273}
274
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000275/** @brief implements mdr2 get directory command
276 * @param agentId
277 * @param dirIndex
278 * @returns IPMI completion code plus response data
279 * - dataOut
280 */
281ipmi::RspType<std::vector<uint8_t>> mdr2GetDir(uint16_t agentId,
282 uint8_t dirIndex)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700283{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700284 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
285 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700286
287 if (mdrv2 == nullptr)
288 {
289 mdrv2 = std::make_unique<MDRV2>();
290 }
291
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000292 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700293 if (agentIndex == -1)
294 {
295 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000296 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
297 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700298 }
299
Jason M. Bills0748c692022-09-08 15:34:08 -0700300 ipmi::DbusVariant value = static_cast<uint8_t>(0);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700301 if (0 != mdrv2->sdplusMdrv2GetProperty("DirectoryEntries", value, service))
302 {
303 phosphor::logging::log<phosphor::logging::level::ERR>(
304 "Error getting DirEnries");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000305 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700306 }
Prithvi A Pai0fac9bf2021-12-27 07:11:24 +0000307 if (std::get<uint8_t>(value) == 0)
308 {
309 phosphor::logging::log<phosphor::logging::level::ERR>(
310 "Error getting directory entries",
311 phosphor::logging::entry("VALUE=%x", std::get<uint8_t>(value)));
312 return ipmi::responseUnspecifiedError();
313 }
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000314 if (dirIndex > std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700315 {
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000316 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700317 }
318
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500319 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700320 service.c_str(), mdrv2Path, mdrv2Interface, "GetDirectoryInformation");
321
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000322 method.append(dirIndex);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700323
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000324 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700325 try
326 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500327 sdbusplus::message_t reply = bus->call(method);
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000328 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700329 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500330 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700331 {
332 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700333 "Error get dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700334 phosphor::logging::entry("SERVICE=%s", service.c_str()),
335 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000336 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700337 }
338
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000339 constexpr size_t getDirRespSize = 6;
340 if (dataOut.size() < getDirRespSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700341 {
342 phosphor::logging::log<phosphor::logging::level::ERR>(
343 "Error get dir, response length invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000344 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700345 }
346
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000347 if (dataOut.size() > MAX_IPMI_BUFFER) // length + completion code should no
348 // more than MAX_IPMI_BUFFER
Vernon Mauerya3702c12019-05-22 13:20:59 -0700349 {
350 phosphor::logging::log<phosphor::logging::level::ERR>(
351 "Data length send from service is invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000352 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700353 }
354
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000355 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700356}
357
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000358/** @brief implements mdr2 send directory info command
359 * @param agentId
360 * @param dirVersion
361 * @param dirIndex
362 * @param returnedEntries
363 * @param remainingEntries
364 * @param dataInfo
365 * dataInfo is 32 Bytes in size and contains below parameters
366 * - dataInfo, size, dataSetSize, dataVersion, timestamp
367 *
368 * @returns IPMI completion code plus response data
369 * - bool
370 */
371
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000372ipmi::RspType<bool> mdr2SendDir(uint16_t agentId, uint8_t dirVersion,
373 uint8_t dirIndex, uint8_t returnedEntries,
374 uint8_t remainingEntries,
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000375 std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700376{
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000377 if ((static_cast<size_t>(returnedEntries) * dataInfoSize) !=
378 dataInfo.size())
379 {
380 return ipmi::responseReqDataLenInvalid();
381 }
382
Vernon Mauery15419dd2019-05-24 09:40:30 -0700383 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
384 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385
386 if (mdrv2 == nullptr)
387 {
388 mdrv2 = std::make_unique<MDRV2>();
389 }
390
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000391 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700392 if (agentIndex == -1)
393 {
394 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000395 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
396 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700397 }
398
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000399 if ((dirIndex + returnedEntries) > maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700400 {
401 phosphor::logging::log<phosphor::logging::level::ERR>(
402 "Too many directory entries");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000403 return ipmi::response(ccStorageLeak);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700404 }
405
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500406 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700407 service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000408 method.append(dirVersion, dirIndex, returnedEntries, remainingEntries,
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000409 dataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700410
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000411 bool terminate = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700412 try
413 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500414 sdbusplus::message_t reply = bus->call(method);
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000415 reply.read(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700416 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500417 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700418 {
419 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700420 "Error send dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700421 phosphor::logging::entry("SERVICE=%s", service.c_str()),
422 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000423 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700424 }
425
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000426 return ipmi::responseSuccess(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700427}
428
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000429/** @brief implements mdr2 get data info command
430 * @param agentId
431 * @param dataInfo
432 *
433 * @returns IPMI completion code plus response data
434 * - response - mdrVersion, data info, validFlag,
435 * dataLength, dataVersion, timeStamp
436 */
437ipmi::RspType<std::vector<uint8_t>>
438 mdr2GetDataInfo(uint16_t agentId, std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700439{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000440 constexpr size_t getDataInfoReqSize = 16;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700441
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000442 if (dataInfo.size() < getDataInfoReqSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700443 {
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000444 return ipmi::responseReqDataLenInvalid();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700445 }
446
Vernon Mauery15419dd2019-05-24 09:40:30 -0700447 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
448 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700449
450 if (mdrv2 == nullptr)
451 {
452 mdrv2 = std::make_unique<MDRV2>();
453 }
454
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000455 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700456 if (agentIndex == -1)
457 {
458 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000459 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
460 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700461 }
462
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000463 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700464
465 if ((idIndex < 0) || (idIndex >= maxDirEntries))
466 {
467 phosphor::logging::log<phosphor::logging::level::ERR>(
468 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000469 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700470 }
471
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500472 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700473 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
474
jayaprakash Mutyala04a38ed2020-05-29 01:42:26 +0000475 method.append(static_cast<uint8_t>(idIndex));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700476
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000477 std::vector<uint8_t> res;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700478 try
479 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500480 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700481 reply.read(res);
482 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500483 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700484 {
485 phosphor::logging::log<phosphor::logging::level::ERR>(
486 "Error get data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700487 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700488 phosphor::logging::entry("SERVICE=%s", service.c_str()),
489 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000490 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700491 }
492
493 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
494 {
495 phosphor::logging::log<phosphor::logging::level::ERR>(
496 "Get data info response length not invalid");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000497 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700498 }
Vernon Mauerya3702c12019-05-22 13:20:59 -0700499
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000500 return ipmi::responseSuccess(res);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700501}
502
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000503/** @brief implements mdr2 data info offer command
504 * @param agentId - Offer a agent ID to get the "Data Set ID"
505 *
506 * @returns IPMI completion code plus response data
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000507 * - dataOut - data Set Id
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000508 */
509ipmi::RspType<std::vector<uint8_t>> mdr2DataInfoOffer(uint16_t agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700510{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700511 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
512 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700513
514 if (mdrv2 == nullptr)
515 {
516 mdrv2 = std::make_unique<MDRV2>();
517 }
518
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000519 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700520 if (agentIndex == -1)
521 {
522 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000523 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
524 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700525 }
526
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500527 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700528 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
529
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000530 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700531 try
532 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500533 sdbusplus::message_t reply = bus->call(method);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000534 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700535 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500536 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700537 {
538 phosphor::logging::log<phosphor::logging::level::ERR>(
539 "Error send data info offer",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700540 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700541 phosphor::logging::entry("SERVICE=%s", service.c_str()),
542 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000543 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700544 }
545
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000546 constexpr size_t respInfoSize = 16;
547 if (dataOut.size() != respInfoSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700548 {
549 phosphor::logging::log<phosphor::logging::level::ERR>(
550 "Error send data info offer, return length invalid");
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000551 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700552 }
553
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000554 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700555}
556
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000557/** @brief implements mdr2 send data info command
558 * @param agentId
559 * @param dataInfo
560 * @param validFlag
561 * @param dataLength
562 * @param dataVersion
563 * @param timeStamp
564 *
565 * @returns IPMI completion code plus response data
566 * - bool
567 */
568ipmi::RspType<bool> mdr2SendDataInfo(uint16_t agentId,
569 std::array<uint8_t, dataInfoSize> dataInfo,
570 uint8_t validFlag, uint32_t dataLength,
571 uint32_t dataVersion, uint32_t timeStamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700572{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000573 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700574 {
575 phosphor::logging::log<phosphor::logging::level::ERR>(
576 "Requested data length is out of SMBIOS Table storage size.");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000577 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700578 }
579
Vernon Mauery15419dd2019-05-24 09:40:30 -0700580 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
581 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700582
583 if (mdrv2 == nullptr)
584 {
585 mdrv2 = std::make_unique<MDRV2>();
586 }
587
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000588 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700589 if (agentIndex == -1)
590 {
591 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000592 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
593 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700594 }
595
Patrick Venture6d765602019-09-25 17:11:07 -0700596 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700597
598 if ((idIndex < 0) || (idIndex >= maxDirEntries))
599 {
600 phosphor::logging::log<phosphor::logging::level::ERR>(
601 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000602 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700603 }
604
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500605 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700606 service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
607
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000608 method.append((uint8_t)idIndex, validFlag, dataLength, dataVersion,
609 timeStamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700610
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000611 bool entryChanged = true;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700612 try
613 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -0500614 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700615 reply.read(entryChanged);
616 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500617 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700618 {
619 phosphor::logging::log<phosphor::logging::level::ERR>(
620 "Error send data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700621 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700622 phosphor::logging::entry("SERVICE=%s", service.c_str()),
623 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000624 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700625 }
626
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000627 return ipmi::responseSuccess(entryChanged);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700628}
629
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000630/**
631@brief This command is MDR related get data block command.
632
633@param - agentId
634@param - lockHandle
635@param - xferOffset
636@param - xferLength
637
638@return on success
639 - xferLength
640 - checksum
641 - data
642**/
643ipmi::RspType<uint32_t, // xferLength
644 uint32_t, // Checksum
645 std::vector<uint8_t> // data
646 >
647 mdr2GetDataBlock(uint16_t agentId, uint16_t lockHandle, uint32_t xferOffset,
648 uint32_t xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700649{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700650 if (mdrv2 == nullptr)
651 {
652 mdrv2 = std::make_unique<MDRV2>();
653 }
654
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000655 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700656 if (agentIndex == -1)
657 {
658 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000659 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
660 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700661 }
662
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000663 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700664
665 if ((idIndex < 0) || (idIndex >= maxDirEntries))
666 {
667 phosphor::logging::log<phosphor::logging::level::ERR>(
668 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000669 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700670 }
671
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000672 if (xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700673 {
674 phosphor::logging::log<phosphor::logging::level::ERR>(
675 "Offset is outside of range.");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000676 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700677 }
678
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000679 size_t outSize = (xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
680 ? mdrv2->smbiosDir.dir[idIndex].xferSize
681 : xferLength;
682 if (outSize > UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700683 {
684 phosphor::logging::log<phosphor::logging::level::ERR>(
685 "Out size and offset are out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000686 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700687 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000688 if ((xferOffset + outSize) > mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700689 {
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000690 outSize = mdrv2->smbiosDir.dir[idIndex].common.size - xferOffset;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700691 }
692
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000693 uint32_t respXferLength = outSize;
694
695 if (respXferLength > xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700696 {
697 phosphor::logging::log<phosphor::logging::level::ERR>(
698 "Get data block unexpected error.");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000699 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700700 }
701
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000702 if ((xferOffset + outSize) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700703 UINT_MAX -
704 reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
705 {
706 phosphor::logging::log<phosphor::logging::level::ERR>(
707 "Input data to calculate checksum is out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000708 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700709 }
710
711 uint32_t u32Checksum = mdrv2->calcChecksum32(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000712 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset, outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700713 if (u32Checksum == invalidChecksum)
714 {
715 phosphor::logging::log<phosphor::logging::level::ERR>(
716 "Get data block failed - invalid checksum");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000717 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700718 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000719 std::vector<uint8_t> data(outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700720
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000721 std::copy(&mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset],
722 &mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset + outSize],
723 data.begin());
Vernon Mauerya3702c12019-05-22 13:20:59 -0700724
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000725 return ipmi::responseSuccess(respXferLength, u32Checksum, data);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700726}
727
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000728/** @brief implements mdr2 send data block command
729 * @param agentId
730 * @param lockHandle
731 * @param xferOffset
732 * @param xferLength
733 * @param checksum
734 *
735 * @returns IPMI completion code
736 */
737ipmi::RspType<> mdr2SendDataBlock(uint16_t agentId, uint16_t lockHandle,
738 uint32_t xferOffset, uint32_t xferLength,
739 uint32_t checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700740{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700741 if (mdrv2 == nullptr)
742 {
743 mdrv2 = std::make_unique<MDRV2>();
744 }
745
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000746 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700747 if (agentIndex == -1)
748 {
749 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000750 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
751 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700752 }
753
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000754 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700755
756 if ((idIndex < 0) || (idIndex >= maxDirEntries))
757 {
758 phosphor::logging::log<phosphor::logging::level::ERR>(
759 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000760 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700761 }
762
763 if (mdrv2->smbiosIsUpdating(idIndex))
764 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000765 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700766 {
767 phosphor::logging::log<phosphor::logging::level::ERR>(
768 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000769 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700770 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000771 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700772 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000773 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700774 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
775 {
776 phosphor::logging::log<phosphor::logging::level::ERR>(
777 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000778 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700779 }
780 if (reinterpret_cast<size_t>(
781 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000782 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700783 {
784 phosphor::logging::log<phosphor::logging::level::ERR>(
785 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000786 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700787 }
Patrick Williamsb37abfb2023-05-10 07:50:33 -0500788 uint8_t* destAddr = mdrv2->smbiosDir.dir[idIndex].dataStorage +
789 xferOffset;
James Feistfcd2d3a2020-05-28 10:38:15 -0700790 uint8_t* sourceAddr = reinterpret_cast<uint8_t*>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000791 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
792 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700793 {
794 phosphor::logging::log<phosphor::logging::level::ERR>(
795 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000796 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700797 }
798 else
799 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000800 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700801 {
802 phosphor::logging::log<phosphor::logging::level::ERR>(
803 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000804 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700805 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000806 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700807 }
808 }
809 else
810 {
811 phosphor::logging::log<phosphor::logging::level::ERR>(
812 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000813 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700814 }
815
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000816 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700817}
818
James Feistfcd2d3a2020-05-28 10:38:15 -0700819bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700820{
821 std::ofstream smbiosFile(mdrType2File,
822 std::ios_base::binary | std::ios_base::trunc);
823 if (!smbiosFile.good())
824 {
825 phosphor::logging::log<phosphor::logging::level::ERR>(
826 "Write data from flash error - Open MDRV2 table file failure");
827 return false;
828 }
829
830 try
831 {
James Feistfcd2d3a2020-05-28 10:38:15 -0700832 smbiosFile.write(reinterpret_cast<char*>(mdrHdr),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700833 sizeof(MDRSMBIOSHeader));
James Feistfcd2d3a2020-05-28 10:38:15 -0700834 smbiosFile.write(reinterpret_cast<char*>(data), mdrHdr->dataSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700835 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500836 catch (const std::ofstream::failure& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700837 {
838 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700839 "Write data from flash error - write data error",
840 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700841 return false;
842 }
843
844 return true;
845}
846
847void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
848{
849 int memDriver = 0;
850
851 // open mem driver for the system memory access
852 memDriver = open("/dev/vgasharedmem", O_RDONLY);
853 if (memDriver < 0)
854 {
855 phosphor::logging::log<phosphor::logging::level::ERR>(
856 "Cannot access mem driver");
857 throw std::system_error(EIO, std::generic_category());
858 }
859
860 // map the system memory
861 vPtr = mmap(NULL, // where to map to: don't mind
862 areaSize, // how many bytes ?
863 PROT_READ, // want to read and write
864 MAP_SHARED, // no copy on write
865 memDriver, // handle to /dev/mem
866 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
867
868 close(memDriver);
869 if (vPtr == MAP_FAILED)
870 {
871 phosphor::logging::log<phosphor::logging::level::ERR>(
872 "Failed to map share memory");
873 throw std::system_error(EIO, std::generic_category());
874 }
875 size = areaSize;
876 physicalAddr = addr;
877}
878
879bool MDRV2::smbiosUnlock(uint8_t index)
880{
P Dheeraj Srujan Kumar36ed8d22021-08-04 01:14:14 +0530881 bool ret = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700882 switch (smbiosDir.dir[index].stage)
883 {
884 case MDR2SMBIOSStatusEnum::mdr2Updating:
885 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
886 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
887
888 timer->stop();
889 smbiosDir.dir[index].lockHandle = 0;
890 ret = true;
891 break;
892
893 case MDR2SMBIOSStatusEnum::mdr2Updated:
894 case MDR2SMBIOSStatusEnum::mdr2Loaded:
895 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
896
897 timer->stop();
898
899 smbiosDir.dir[index].lockHandle = 0;
900 ret = true;
901 break;
902
903 default:
904 break;
905 }
906
907 return ret;
908}
909
James Feistfcd2d3a2020-05-28 10:38:15 -0700910bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700911 uint16_t timeout)
912{
913 bool ret = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700914
915 if (timeout == 0)
916 {
917 timeout = defaultTimeout;
918 }
919 std::chrono::microseconds usec(timeout * sysClock);
920
921 switch (smbiosDir.dir[index].stage)
922 {
923 case MDR2SMBIOSStatusEnum::mdr2Updating:
924 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
925 {
926 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
927 timer->start(usec);
928 lockIndex = index;
929
930 *session = getSessionHandle(&smbiosDir);
931 smbiosDir.dir[index].lockHandle = *session;
932 ret = true;
933 }
934 break;
935 case MDR2SMBIOSStatusEnum::mdr2Init:
936 if (flag)
937 {
938 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
939 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
940 timer->start(usec);
941 lockIndex = index;
942
943 *session = getSessionHandle(&smbiosDir);
944 smbiosDir.dir[index].lockHandle = *session;
945 ret = true;
946 }
947 break;
948
949 case MDR2SMBIOSStatusEnum::mdr2Updated:
950 case MDR2SMBIOSStatusEnum::mdr2Loaded:
951 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
952 {
953 if (flag)
954 {
955 smbiosDir.dir[index].stage =
956 MDR2SMBIOSStatusEnum::mdr2Updating;
957 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
958 }
959 else
960 {
961 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
962 }
963
964 timer->start(usec);
965 lockIndex = index;
966
967 *session = getSessionHandle(&smbiosDir);
968 smbiosDir.dir[index].lockHandle = *session;
969 ret = true;
970 }
971 break;
972
973 default:
974 break;
975 }
976 return ret;
977}
978
979void MDRV2::timeoutHandler()
980{
981 smbiosUnlock(lockIndex);
982 mdrv2->area.reset(nullptr);
983}
984
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000985/** @brief implements mdr2 lock data command
986 * @param agentId
987 * @param dataInfo
988 * @param timeout
989 *
990 * @returns IPMI completion code plus response data
991 * - mdr2Version
992 * - session
993 * - dataLength
994 * - xferAddress
995 * - xferLength
996 */
997ipmi::RspType<uint8_t, // mdr2Version
998 uint16_t, // session
999 uint32_t, // dataLength
1000 uint32_t, // xferAddress
1001 uint32_t // xferLength
1002 >
1003 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
1004 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001005{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001006 if (mdrv2 == nullptr)
1007 {
1008 mdrv2 = std::make_unique<MDRV2>();
1009 }
1010
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001011 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001012 if (agentIndex == -1)
1013 {
1014 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001015 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1016 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001017 }
1018
Vernon Mauery15419dd2019-05-24 09:40:30 -07001019 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1020 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001021
Patrick Venture6d765602019-09-25 17:11:07 -07001022 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001023
1024 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1025 {
1026 phosphor::logging::log<phosphor::logging::level::ERR>(
1027 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001028 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001029 }
1030
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001031 uint16_t session = 0;
1032 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001033 {
1034 phosphor::logging::log<phosphor::logging::level::ERR>(
1035 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001036 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001037 }
1038
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001039 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1040 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1041 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001042
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001043 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1044 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001045}
1046
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001047/** @brief implements mdr2 unlock data command
1048 * @param agentId
1049 * @param lockHandle
1050 *
1051 * @returns IPMI completion code
1052 */
1053ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001054{
1055 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001056
Vernon Mauerya3702c12019-05-22 13:20:59 -07001057 if (mdrv2 == nullptr)
1058 {
1059 mdrv2 = std::make_unique<MDRV2>();
1060 }
1061
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001062 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001063 if (agentIndex == -1)
1064 {
1065 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001066 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1067 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001068 }
1069
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001070 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001071
1072 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1073 {
1074 phosphor::logging::log<phosphor::logging::level::ERR>(
1075 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001076 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001077 }
1078
1079 if (!mdrv2->smbiosUnlock(idIndex))
1080 {
1081 phosphor::logging::log<phosphor::logging::level::ERR>(
1082 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001083 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001084 }
1085
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001086 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001087}
1088
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001089/**
1090@brief This command is executed after POST BIOS to get the session info.
1091
1092@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1093
1094@return xferStartAck and session on success.
1095**/
1096ipmi::RspType<uint8_t, uint16_t>
1097 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1098 uint32_t dataLength, uint32_t xferAddress,
1099 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001100{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001101 uint16_t session = 0;
1102
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001103 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001104 {
1105 phosphor::logging::log<phosphor::logging::level::ERR>(
1106 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001107 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001108 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001109 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001110 {
1111 phosphor::logging::log<phosphor::logging::level::ERR>(
1112 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001113 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001114 }
1115
Vernon Mauery15419dd2019-05-24 09:40:30 -07001116 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1117 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001118
1119 if (mdrv2 == nullptr)
1120 {
1121 mdrv2 = std::make_unique<MDRV2>();
1122 }
1123
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001124 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001125 if (agentIndex == -1)
1126 {
1127 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001128 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1129 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001130 }
1131
Patrick Venture6d765602019-09-25 17:11:07 -07001132 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001133
1134 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1135 {
1136 phosphor::logging::log<phosphor::logging::level::ERR>(
1137 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001138 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001139 }
1140
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001141 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001142 {
1143 try
1144 {
Patrick Williamsb37abfb2023-05-10 07:50:33 -05001145 mdrv2->area = std::make_unique<SharedMemoryArea>(xferAddress,
1146 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001147 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001148 catch (const std::system_error& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001149 {
1150 mdrv2->smbiosUnlock(idIndex);
1151 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001152 "Unable to access share memory",
1153 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001154 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001155 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001156 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001157 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1158 if (-1 ==
1159 mdrv2->syncDirCommonData(
1160 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1161 {
1162 phosphor::logging::log<phosphor::logging::level::ERR>(
1163 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001164 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001165 }
1166 }
1167 else
1168 {
1169 phosphor::logging::log<phosphor::logging::level::ERR>(
1170 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001171 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001172 }
1173
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001174 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001175
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001176 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001177}
1178
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001179/**
1180@brief This command is executed to close the session.
1181
1182@param - agentId, lockHandle.
1183
1184@return completion code on success.
1185**/
1186ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001187{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001188 if (mdrv2 == nullptr)
1189 {
1190 mdrv2 = std::make_unique<MDRV2>();
1191 }
1192
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001193 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001194 if (agentIndex == -1)
1195 {
1196 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001197 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1198 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001199 }
1200
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001201 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001202
1203 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1204 {
1205 phosphor::logging::log<phosphor::logging::level::ERR>(
1206 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001207 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001208 }
1209
1210 if (!mdrv2->smbiosUnlock(idIndex))
1211 {
1212 phosphor::logging::log<phosphor::logging::level::ERR>(
1213 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001214 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001215 }
1216
1217 mdrv2->area.reset(nullptr);
1218 MDRSMBIOSHeader mdr2Smbios;
1219 mdr2Smbios.mdrType = mdrTypeII;
1220 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1221 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1222 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1223
1224 if (access(smbiosPath, 0) == -1)
1225 {
1226 int flag = mkdir(smbiosPath, S_IRWXU);
1227 if (flag != 0)
1228 {
1229 phosphor::logging::log<phosphor::logging::level::ERR>(
1230 "create folder failed for writting smbios file");
1231 }
1232 }
1233 if (!mdrv2->storeDatatoFlash(
1234 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1235 {
1236 phosphor::logging::log<phosphor::logging::level::ERR>(
1237 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001238 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001239 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001240 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001241 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1242 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001243 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001244 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1245
1246 try
1247 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001248 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001249 reply.read(status);
1250 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -05001251 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001252 {
1253 phosphor::logging::log<phosphor::logging::level::ERR>(
1254 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001255 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001256 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1257 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001258 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001259 }
1260
1261 if (!status)
1262 {
1263 phosphor::logging::log<phosphor::logging::level::ERR>(
1264 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001265 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001266 }
1267
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001268 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001269}
1270
1271static void register_netfn_smbiosmdrv2_functions(void)
1272{
1273 // MDR V2 Command
1274 // <Get MDRII Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001275 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1276 ipmi::intel::app::cmdMdrIIAgentStatus,
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001277 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001278
1279 // <Get MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001280 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1281 ipmi::intel::app::cmdMdrIIGetDir,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001282 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001283
1284 // <Send MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001285 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1286 ipmi::intel::app::cmdMdrIISendDir,
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001287 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001288
1289 // <Get MDRII Data Info Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001290 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1291 ipmi::intel::app::cmdMdrIIGetDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001292 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001293
1294 // <Send MDRII Info Offer>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001295 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1296 ipmi::intel::app::cmdMdrIISendDataInfoOffer,
1297 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001298
1299 // <Send MDRII Data Info>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001300 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1301 ipmi::intel::app::cmdMdrIISendDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001302 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001303
1304 // <Get MDRII Data Block Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001305 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1306 ipmi::intel::app::cmdMdrIIGetDataBlock,
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +00001307 ipmi::Privilege::Operator, mdr2GetDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001308
1309 // <Send MDRII Data Block>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001310 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1311 ipmi::intel::app::cmdMdrIISendDataBlock,
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001312 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001313
1314 // <Lock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001315 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1316 ipmi::intel::app::cmdMdrIILockData,
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001317 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001318
1319 // <Unlock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001320 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1321 ipmi::intel::app::cmdMdrIIUnlockData,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001322 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001323
1324 // <Send MDRII Data Start>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001325 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1326 ipmi::intel::app::cmdMdrIIDataStart,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001327 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001328
1329 // <Send MDRII Data Done>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001330 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1331 ipmi::intel::app::cmdMdrIIDataDone,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001332 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001333}