blob: c5d00a19966e207b917aae4f69af52929f2cbab8 [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{
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000741
Vernon Mauerya3702c12019-05-22 13:20:59 -0700742 if (mdrv2 == nullptr)
743 {
744 mdrv2 = std::make_unique<MDRV2>();
745 }
746
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000747 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700748 if (agentIndex == -1)
749 {
750 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000751 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
752 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700753 }
754
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000755 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700756
757 if ((idIndex < 0) || (idIndex >= maxDirEntries))
758 {
759 phosphor::logging::log<phosphor::logging::level::ERR>(
760 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000761 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700762 }
763
764 if (mdrv2->smbiosIsUpdating(idIndex))
765 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000766 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700767 {
768 phosphor::logging::log<phosphor::logging::level::ERR>(
769 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000770 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700771 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000772 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700773 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000774 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700775 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
776 {
777 phosphor::logging::log<phosphor::logging::level::ERR>(
778 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000779 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700780 }
781 if (reinterpret_cast<size_t>(
782 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000783 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700784 {
785 phosphor::logging::log<phosphor::logging::level::ERR>(
786 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000787 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700788 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700789 uint8_t* destAddr =
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000790 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset;
James Feistfcd2d3a2020-05-28 10:38:15 -0700791 uint8_t* sourceAddr = reinterpret_cast<uint8_t*>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000792 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
793 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700794 {
795 phosphor::logging::log<phosphor::logging::level::ERR>(
796 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000797 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700798 }
799 else
800 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000801 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700802 {
803 phosphor::logging::log<phosphor::logging::level::ERR>(
804 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000805 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700806 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000807 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700808 }
809 }
810 else
811 {
812 phosphor::logging::log<phosphor::logging::level::ERR>(
813 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000814 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700815 }
816
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000817 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700818}
819
James Feistfcd2d3a2020-05-28 10:38:15 -0700820bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700821{
822 std::ofstream smbiosFile(mdrType2File,
823 std::ios_base::binary | std::ios_base::trunc);
824 if (!smbiosFile.good())
825 {
826 phosphor::logging::log<phosphor::logging::level::ERR>(
827 "Write data from flash error - Open MDRV2 table file failure");
828 return false;
829 }
830
831 try
832 {
James Feistfcd2d3a2020-05-28 10:38:15 -0700833 smbiosFile.write(reinterpret_cast<char*>(mdrHdr),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700834 sizeof(MDRSMBIOSHeader));
James Feistfcd2d3a2020-05-28 10:38:15 -0700835 smbiosFile.write(reinterpret_cast<char*>(data), mdrHdr->dataSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700836 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500837 catch (const std::ofstream::failure& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700838 {
839 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700840 "Write data from flash error - write data error",
841 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700842 return false;
843 }
844
845 return true;
846}
847
848void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
849{
850 int memDriver = 0;
851
852 // open mem driver for the system memory access
853 memDriver = open("/dev/vgasharedmem", O_RDONLY);
854 if (memDriver < 0)
855 {
856 phosphor::logging::log<phosphor::logging::level::ERR>(
857 "Cannot access mem driver");
858 throw std::system_error(EIO, std::generic_category());
859 }
860
861 // map the system memory
862 vPtr = mmap(NULL, // where to map to: don't mind
863 areaSize, // how many bytes ?
864 PROT_READ, // want to read and write
865 MAP_SHARED, // no copy on write
866 memDriver, // handle to /dev/mem
867 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
868
869 close(memDriver);
870 if (vPtr == MAP_FAILED)
871 {
872 phosphor::logging::log<phosphor::logging::level::ERR>(
873 "Failed to map share memory");
874 throw std::system_error(EIO, std::generic_category());
875 }
876 size = areaSize;
877 physicalAddr = addr;
878}
879
880bool MDRV2::smbiosUnlock(uint8_t index)
881{
P Dheeraj Srujan Kumar36ed8d22021-08-04 01:14:14 +0530882 bool ret = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700883 switch (smbiosDir.dir[index].stage)
884 {
885 case MDR2SMBIOSStatusEnum::mdr2Updating:
886 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
887 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
888
889 timer->stop();
890 smbiosDir.dir[index].lockHandle = 0;
891 ret = true;
892 break;
893
894 case MDR2SMBIOSStatusEnum::mdr2Updated:
895 case MDR2SMBIOSStatusEnum::mdr2Loaded:
896 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
897
898 timer->stop();
899
900 smbiosDir.dir[index].lockHandle = 0;
901 ret = true;
902 break;
903
904 default:
905 break;
906 }
907
908 return ret;
909}
910
James Feistfcd2d3a2020-05-28 10:38:15 -0700911bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700912 uint16_t timeout)
913{
914 bool ret = false;
915 uint32_t u32Status = 0;
916
917 if (timeout == 0)
918 {
919 timeout = defaultTimeout;
920 }
921 std::chrono::microseconds usec(timeout * sysClock);
922
923 switch (smbiosDir.dir[index].stage)
924 {
925 case MDR2SMBIOSStatusEnum::mdr2Updating:
926 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
927 {
928 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
929 timer->start(usec);
930 lockIndex = index;
931
932 *session = getSessionHandle(&smbiosDir);
933 smbiosDir.dir[index].lockHandle = *session;
934 ret = true;
935 }
936 break;
937 case MDR2SMBIOSStatusEnum::mdr2Init:
938 if (flag)
939 {
940 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
941 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
942 timer->start(usec);
943 lockIndex = index;
944
945 *session = getSessionHandle(&smbiosDir);
946 smbiosDir.dir[index].lockHandle = *session;
947 ret = true;
948 }
949 break;
950
951 case MDR2SMBIOSStatusEnum::mdr2Updated:
952 case MDR2SMBIOSStatusEnum::mdr2Loaded:
953 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
954 {
955 if (flag)
956 {
957 smbiosDir.dir[index].stage =
958 MDR2SMBIOSStatusEnum::mdr2Updating;
959 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
960 }
961 else
962 {
963 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
964 }
965
966 timer->start(usec);
967 lockIndex = index;
968
969 *session = getSessionHandle(&smbiosDir);
970 smbiosDir.dir[index].lockHandle = *session;
971 ret = true;
972 }
973 break;
974
975 default:
976 break;
977 }
978 return ret;
979}
980
981void MDRV2::timeoutHandler()
982{
983 smbiosUnlock(lockIndex);
984 mdrv2->area.reset(nullptr);
985}
986
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000987/** @brief implements mdr2 lock data command
988 * @param agentId
989 * @param dataInfo
990 * @param timeout
991 *
992 * @returns IPMI completion code plus response data
993 * - mdr2Version
994 * - session
995 * - dataLength
996 * - xferAddress
997 * - xferLength
998 */
999ipmi::RspType<uint8_t, // mdr2Version
1000 uint16_t, // session
1001 uint32_t, // dataLength
1002 uint32_t, // xferAddress
1003 uint32_t // xferLength
1004 >
1005 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
1006 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001007{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001008 if (mdrv2 == nullptr)
1009 {
1010 mdrv2 = std::make_unique<MDRV2>();
1011 }
1012
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001013 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001014 if (agentIndex == -1)
1015 {
1016 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001017 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1018 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001019 }
1020
Vernon Mauery15419dd2019-05-24 09:40:30 -07001021 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1022 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001023
Patrick Venture6d765602019-09-25 17:11:07 -07001024 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001025
1026 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1027 {
1028 phosphor::logging::log<phosphor::logging::level::ERR>(
1029 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001030 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001031 }
1032
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001033 uint16_t session = 0;
1034 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001035 {
1036 phosphor::logging::log<phosphor::logging::level::ERR>(
1037 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001038 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001039 }
1040
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001041 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1042 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1043 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001044
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001045 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1046 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001047}
1048
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001049/** @brief implements mdr2 unlock data command
1050 * @param agentId
1051 * @param lockHandle
1052 *
1053 * @returns IPMI completion code
1054 */
1055ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001056{
1057 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001058
Vernon Mauerya3702c12019-05-22 13:20:59 -07001059 if (mdrv2 == nullptr)
1060 {
1061 mdrv2 = std::make_unique<MDRV2>();
1062 }
1063
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001064 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001065 if (agentIndex == -1)
1066 {
1067 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001068 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1069 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001070 }
1071
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001072 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001073
1074 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1075 {
1076 phosphor::logging::log<phosphor::logging::level::ERR>(
1077 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001078 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001079 }
1080
1081 if (!mdrv2->smbiosUnlock(idIndex))
1082 {
1083 phosphor::logging::log<phosphor::logging::level::ERR>(
1084 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001085 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001086 }
1087
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001088 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001089}
1090
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001091/**
1092@brief This command is executed after POST BIOS to get the session info.
1093
1094@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1095
1096@return xferStartAck and session on success.
1097**/
1098ipmi::RspType<uint8_t, uint16_t>
1099 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1100 uint32_t dataLength, uint32_t xferAddress,
1101 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001102{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001103 uint16_t session = 0;
1104
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001105 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001106 {
1107 phosphor::logging::log<phosphor::logging::level::ERR>(
1108 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001109 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001110 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001111 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001112 {
1113 phosphor::logging::log<phosphor::logging::level::ERR>(
1114 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001115 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001116 }
1117
Vernon Mauery15419dd2019-05-24 09:40:30 -07001118 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1119 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001120
1121 if (mdrv2 == nullptr)
1122 {
1123 mdrv2 = std::make_unique<MDRV2>();
1124 }
1125
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001126 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001127 if (agentIndex == -1)
1128 {
1129 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001130 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1131 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001132 }
1133
Patrick Venture6d765602019-09-25 17:11:07 -07001134 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001135
1136 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1137 {
1138 phosphor::logging::log<phosphor::logging::level::ERR>(
1139 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001140 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001141 }
1142
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001143 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001144 {
1145 try
1146 {
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001147 mdrv2->area =
1148 std::make_unique<SharedMemoryArea>(xferAddress, xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001149 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001150 catch (const std::system_error& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001151 {
1152 mdrv2->smbiosUnlock(idIndex);
1153 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001154 "Unable to access share memory",
1155 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001156 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001157 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001158 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001159 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1160 if (-1 ==
1161 mdrv2->syncDirCommonData(
1162 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1163 {
1164 phosphor::logging::log<phosphor::logging::level::ERR>(
1165 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001166 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001167 }
1168 }
1169 else
1170 {
1171 phosphor::logging::log<phosphor::logging::level::ERR>(
1172 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001173 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001174 }
1175
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001176 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001177
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001178 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001179}
1180
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001181/**
1182@brief This command is executed to close the session.
1183
1184@param - agentId, lockHandle.
1185
1186@return completion code on success.
1187**/
1188ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001189{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001190
1191 if (mdrv2 == nullptr)
1192 {
1193 mdrv2 = std::make_unique<MDRV2>();
1194 }
1195
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001196 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001197 if (agentIndex == -1)
1198 {
1199 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001200 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1201 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001202 }
1203
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001204 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001205
1206 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1207 {
1208 phosphor::logging::log<phosphor::logging::level::ERR>(
1209 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001210 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001211 }
1212
1213 if (!mdrv2->smbiosUnlock(idIndex))
1214 {
1215 phosphor::logging::log<phosphor::logging::level::ERR>(
1216 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001217 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001218 }
1219
1220 mdrv2->area.reset(nullptr);
1221 MDRSMBIOSHeader mdr2Smbios;
1222 mdr2Smbios.mdrType = mdrTypeII;
1223 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1224 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1225 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1226
1227 if (access(smbiosPath, 0) == -1)
1228 {
1229 int flag = mkdir(smbiosPath, S_IRWXU);
1230 if (flag != 0)
1231 {
1232 phosphor::logging::log<phosphor::logging::level::ERR>(
1233 "create folder failed for writting smbios file");
1234 }
1235 }
1236 if (!mdrv2->storeDatatoFlash(
1237 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1238 {
1239 phosphor::logging::log<phosphor::logging::level::ERR>(
1240 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001241 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001242 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001243 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001244 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1245 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001246 sdbusplus::message_t method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001247 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1248
1249 try
1250 {
Patrick Williamsf944d2e2022-07-22 19:26:52 -05001251 sdbusplus::message_t reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001252 reply.read(status);
1253 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -05001254 catch (const sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001255 {
1256 phosphor::logging::log<phosphor::logging::level::ERR>(
1257 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001258 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001259 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1260 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001261 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001262 }
1263
1264 if (!status)
1265 {
1266 phosphor::logging::log<phosphor::logging::level::ERR>(
1267 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001268 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001269 }
1270
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001271 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001272}
1273
1274static void register_netfn_smbiosmdrv2_functions(void)
1275{
1276 // MDR V2 Command
1277 // <Get MDRII Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001278 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1279 ipmi::intel::app::cmdMdrIIAgentStatus,
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001280 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001281
1282 // <Get MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001283 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1284 ipmi::intel::app::cmdMdrIIGetDir,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001285 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001286
1287 // <Send MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001288 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1289 ipmi::intel::app::cmdMdrIISendDir,
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001290 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001291
1292 // <Get MDRII Data Info Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001293 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1294 ipmi::intel::app::cmdMdrIIGetDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001295 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001296
1297 // <Send MDRII Info Offer>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001298 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1299 ipmi::intel::app::cmdMdrIISendDataInfoOffer,
1300 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001301
1302 // <Send MDRII Data Info>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001303 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1304 ipmi::intel::app::cmdMdrIISendDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001305 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001306
1307 // <Get MDRII Data Block Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001308 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1309 ipmi::intel::app::cmdMdrIIGetDataBlock,
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +00001310 ipmi::Privilege::Operator, mdr2GetDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001311
1312 // <Send MDRII Data Block>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001313 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1314 ipmi::intel::app::cmdMdrIISendDataBlock,
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001315 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001316
1317 // <Lock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001318 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1319 ipmi::intel::app::cmdMdrIILockData,
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001320 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001321
1322 // <Unlock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001323 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1324 ipmi::intel::app::cmdMdrIIUnlockData,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001325 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001326
1327 // <Send MDRII Data Start>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001328 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1329 ipmi::intel::app::cmdMdrIIDataStart,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001330 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001331
1332 // <Send MDRII Data Done>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001333 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1334 ipmi::intel::app::cmdMdrIIDataDone,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001335 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001336}