blob: fac3d946f82af8cea2adbf96b5eb30305d61dcb5 [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;
914 uint32_t u32Status = 0;
915
916 if (timeout == 0)
917 {
918 timeout = defaultTimeout;
919 }
920 std::chrono::microseconds usec(timeout * sysClock);
921
922 switch (smbiosDir.dir[index].stage)
923 {
924 case MDR2SMBIOSStatusEnum::mdr2Updating:
925 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
926 {
927 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
928 timer->start(usec);
929 lockIndex = index;
930
931 *session = getSessionHandle(&smbiosDir);
932 smbiosDir.dir[index].lockHandle = *session;
933 ret = true;
934 }
935 break;
936 case MDR2SMBIOSStatusEnum::mdr2Init:
937 if (flag)
938 {
939 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
940 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
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
950 case MDR2SMBIOSStatusEnum::mdr2Updated:
951 case MDR2SMBIOSStatusEnum::mdr2Loaded:
952 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
953 {
954 if (flag)
955 {
956 smbiosDir.dir[index].stage =
957 MDR2SMBIOSStatusEnum::mdr2Updating;
958 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
959 }
960 else
961 {
962 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
963 }
964
965 timer->start(usec);
966 lockIndex = index;
967
968 *session = getSessionHandle(&smbiosDir);
969 smbiosDir.dir[index].lockHandle = *session;
970 ret = true;
971 }
972 break;
973
974 default:
975 break;
976 }
977 return ret;
978}
979
980void MDRV2::timeoutHandler()
981{
982 smbiosUnlock(lockIndex);
983 mdrv2->area.reset(nullptr);
984}
985
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000986/** @brief implements mdr2 lock data command
987 * @param agentId
988 * @param dataInfo
989 * @param timeout
990 *
991 * @returns IPMI completion code plus response data
992 * - mdr2Version
993 * - session
994 * - dataLength
995 * - xferAddress
996 * - xferLength
997 */
998ipmi::RspType<uint8_t, // mdr2Version
999 uint16_t, // session
1000 uint32_t, // dataLength
1001 uint32_t, // xferAddress
1002 uint32_t // xferLength
1003 >
1004 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
1005 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001006{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001007 if (mdrv2 == nullptr)
1008 {
1009 mdrv2 = std::make_unique<MDRV2>();
1010 }
1011
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001012 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001013 if (agentIndex == -1)
1014 {
1015 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001016 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1017 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001018 }
1019
Vernon Mauery15419dd2019-05-24 09:40:30 -07001020 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1021 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001022
Patrick Venture6d765602019-09-25 17:11:07 -07001023 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001024
1025 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1026 {
1027 phosphor::logging::log<phosphor::logging::level::ERR>(
1028 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001029 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001030 }
1031
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001032 uint16_t session = 0;
1033 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001034 {
1035 phosphor::logging::log<phosphor::logging::level::ERR>(
1036 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001037 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001038 }
1039
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001040 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1041 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1042 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001043
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001044 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1045 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001046}
1047
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001048/** @brief implements mdr2 unlock data command
1049 * @param agentId
1050 * @param lockHandle
1051 *
1052 * @returns IPMI completion code
1053 */
1054ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001055{
1056 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001057
Vernon Mauerya3702c12019-05-22 13:20:59 -07001058 if (mdrv2 == nullptr)
1059 {
1060 mdrv2 = std::make_unique<MDRV2>();
1061 }
1062
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001063 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001064 if (agentIndex == -1)
1065 {
1066 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001067 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1068 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001069 }
1070
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001071 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001072
1073 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1074 {
1075 phosphor::logging::log<phosphor::logging::level::ERR>(
1076 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001077 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001078 }
1079
1080 if (!mdrv2->smbiosUnlock(idIndex))
1081 {
1082 phosphor::logging::log<phosphor::logging::level::ERR>(
1083 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001084 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001085 }
1086
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001087 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001088}
1089
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001090/**
1091@brief This command is executed after POST BIOS to get the session info.
1092
1093@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1094
1095@return xferStartAck and session on success.
1096**/
1097ipmi::RspType<uint8_t, uint16_t>
1098 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1099 uint32_t dataLength, uint32_t xferAddress,
1100 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001101{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001102 uint16_t session = 0;
1103
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001104 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001105 {
1106 phosphor::logging::log<phosphor::logging::level::ERR>(
1107 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001108 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001109 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001110 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001111 {
1112 phosphor::logging::log<phosphor::logging::level::ERR>(
1113 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001114 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001115 }
1116
Vernon Mauery15419dd2019-05-24 09:40:30 -07001117 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1118 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001119
1120 if (mdrv2 == nullptr)
1121 {
1122 mdrv2 = std::make_unique<MDRV2>();
1123 }
1124
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001125 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001126 if (agentIndex == -1)
1127 {
1128 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001129 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1130 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001131 }
1132
Patrick Venture6d765602019-09-25 17:11:07 -07001133 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001134
1135 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1136 {
1137 phosphor::logging::log<phosphor::logging::level::ERR>(
1138 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001139 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001140 }
1141
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001142 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001143 {
1144 try
1145 {
Patrick Williamsb37abfb2023-05-10 07:50:33 -05001146 mdrv2->area = std::make_unique<SharedMemoryArea>(xferAddress,
1147 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001148 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001149 catch (const std::system_error& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001150 {
1151 mdrv2->smbiosUnlock(idIndex);
1152 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001153 "Unable to access share memory",
1154 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001155 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001156 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001157 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001158 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1159 if (-1 ==
1160 mdrv2->syncDirCommonData(
1161 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1162 {
1163 phosphor::logging::log<phosphor::logging::level::ERR>(
1164 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001165 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001166 }
1167 }
1168 else
1169 {
1170 phosphor::logging::log<phosphor::logging::level::ERR>(
1171 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001172 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001173 }
1174
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001175 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001176
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001177 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001178}
1179
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001180/**
1181@brief This command is executed to close the session.
1182
1183@param - agentId, lockHandle.
1184
1185@return completion code on success.
1186**/
1187ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001188{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001189 if (mdrv2 == nullptr)
1190 {
1191 mdrv2 = std::make_unique<MDRV2>();
1192 }
1193
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001194 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001195 if (agentIndex == -1)
1196 {
1197 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001198 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1199 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001200 }
1201
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001202 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001203
1204 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1205 {
1206 phosphor::logging::log<phosphor::logging::level::ERR>(
1207 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001208 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001209 }
1210
1211 if (!mdrv2->smbiosUnlock(idIndex))
1212 {
1213 phosphor::logging::log<phosphor::logging::level::ERR>(
1214 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001215 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001216 }
1217
1218 mdrv2->area.reset(nullptr);
1219 MDRSMBIOSHeader mdr2Smbios;
1220 mdr2Smbios.mdrType = mdrTypeII;
1221 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1222 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1223 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1224
1225 if (access(smbiosPath, 0) == -1)
1226 {
1227 int flag = mkdir(smbiosPath, S_IRWXU);
1228 if (flag != 0)
1229 {
1230 phosphor::logging::log<phosphor::logging::level::ERR>(
1231 "create folder failed for writting smbios file");
1232 }
1233 }
1234 if (!mdrv2->storeDatatoFlash(
1235 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1236 {
1237 phosphor::logging::log<phosphor::logging::level::ERR>(
1238 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001239 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001240 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001241 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001242 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1243 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001244 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001245 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1246
1247 try
1248 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001249 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001250 reply.read(status);
1251 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -05001252 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001253 {
1254 phosphor::logging::log<phosphor::logging::level::ERR>(
1255 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001256 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001257 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1258 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001259 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001260 }
1261
1262 if (!status)
1263 {
1264 phosphor::logging::log<phosphor::logging::level::ERR>(
1265 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001266 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001267 }
1268
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001269 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001270}
1271
1272static void register_netfn_smbiosmdrv2_functions(void)
1273{
1274 // MDR V2 Command
1275 // <Get MDRII Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001276 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1277 ipmi::intel::app::cmdMdrIIAgentStatus,
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001278 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001279
1280 // <Get MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001281 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1282 ipmi::intel::app::cmdMdrIIGetDir,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001283 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001284
1285 // <Send MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001286 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1287 ipmi::intel::app::cmdMdrIISendDir,
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001288 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001289
1290 // <Get MDRII Data Info Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001291 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1292 ipmi::intel::app::cmdMdrIIGetDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001293 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001294
1295 // <Send MDRII Info Offer>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001296 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1297 ipmi::intel::app::cmdMdrIISendDataInfoOffer,
1298 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001299
1300 // <Send MDRII Data Info>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001301 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1302 ipmi::intel::app::cmdMdrIISendDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001303 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001304
1305 // <Get MDRII Data Block Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001306 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1307 ipmi::intel::app::cmdMdrIIGetDataBlock,
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +00001308 ipmi::Privilege::Operator, mdr2GetDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001309
1310 // <Send MDRII Data Block>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001311 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1312 ipmi::intel::app::cmdMdrIISendDataBlock,
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001313 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001314
1315 // <Lock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001316 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1317 ipmi::intel::app::cmdMdrIILockData,
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001318 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001319
1320 // <Unlock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001321 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1322 ipmi::intel::app::cmdMdrIIUnlockData,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001323 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001324
1325 // <Send MDRII Data Start>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001326 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1327 ipmi::intel::app::cmdMdrIIDataStart,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001328 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001329
1330 // <Send MDRII Data Done>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001331 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1332 ipmi::intel::app::cmdMdrIIDataDone,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001333 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001334}