blob: 55cd79a8b742d3f4952ce1a6773fb15a378663dc [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,
63 std::variant<uint8_t>& value,
64 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();
Vernon Mauerya3702c12019-05-22 13:20:59 -070067 sdbusplus::message::message 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
Vernon Mauery15419dd2019-05-24 09:40:30 -070071 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070072
73 try
74 {
Vernon Mauery15419dd2019-05-24 09:40:30 -070075 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070076 reply.read(value);
77 }
James Feistfcd2d3a2020-05-28 10:38:15 -070078 catch (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();
Vernon Mauerya3702c12019-05-22 13:20:59 -070094 sdbusplus::message::message 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 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700101 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700102 reply.read(commonData);
103 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700104 catch (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();
138 sdbusplus::message::message 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 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700147 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700148 reply.read(idIndex);
149 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700150 catch (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
James Feist5ee2d8d2020-05-27 11:20:35 -0700300 std::variant<uint8_t> 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 }
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000307 if (dirIndex > std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700308 {
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000309 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700310 }
311
Vernon Mauery15419dd2019-05-24 09:40:30 -0700312 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700313 service.c_str(), mdrv2Path, mdrv2Interface, "GetDirectoryInformation");
314
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000315 method.append(dirIndex);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700316
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000317 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700318 try
319 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700320 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000321 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700322 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700323 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700324 {
325 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700326 "Error get dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700327 phosphor::logging::entry("SERVICE=%s", service.c_str()),
328 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000329 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700330 }
331
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000332 constexpr size_t getDirRespSize = 6;
333 if (dataOut.size() < getDirRespSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700334 {
335 phosphor::logging::log<phosphor::logging::level::ERR>(
336 "Error get dir, response length invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000337 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700338 }
339
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000340 if (dataOut.size() > MAX_IPMI_BUFFER) // length + completion code should no
341 // more than MAX_IPMI_BUFFER
Vernon Mauerya3702c12019-05-22 13:20:59 -0700342 {
343 phosphor::logging::log<phosphor::logging::level::ERR>(
344 "Data length send from service is invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000345 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700346 }
347
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000348 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700349}
350
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000351/** @brief implements mdr2 send directory info command
352 * @param agentId
353 * @param dirVersion
354 * @param dirIndex
355 * @param returnedEntries
356 * @param remainingEntries
357 * @param dataInfo
358 * dataInfo is 32 Bytes in size and contains below parameters
359 * - dataInfo, size, dataSetSize, dataVersion, timestamp
360 *
361 * @returns IPMI completion code plus response data
362 * - bool
363 */
364
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000365ipmi::RspType<bool> mdr2SendDir(uint16_t agentId, uint8_t dirVersion,
366 uint8_t dirIndex, uint8_t returnedEntries,
367 uint8_t remainingEntries,
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000368 std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700369{
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000370 if ((static_cast<size_t>(returnedEntries) * dataInfoSize) !=
371 dataInfo.size())
372 {
373 return ipmi::responseReqDataLenInvalid();
374 }
375
Vernon Mauery15419dd2019-05-24 09:40:30 -0700376 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
377 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700378
379 if (mdrv2 == nullptr)
380 {
381 mdrv2 = std::make_unique<MDRV2>();
382 }
383
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000384 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385 if (agentIndex == -1)
386 {
387 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000388 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
389 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700390 }
391
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000392 if ((dirIndex + returnedEntries) > maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700393 {
394 phosphor::logging::log<phosphor::logging::level::ERR>(
395 "Too many directory entries");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000396 return ipmi::response(ccStorageLeak);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700397 }
398
Vernon Mauery15419dd2019-05-24 09:40:30 -0700399 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700400 service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000401 method.append(dirVersion, dirIndex, returnedEntries, remainingEntries,
Jayaprakash Mutyala5235ae92021-03-22 22:33:07 +0000402 dataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700403
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000404 bool terminate = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700405 try
406 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700407 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000408 reply.read(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700409 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700410 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700411 {
412 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700413 "Error send dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700414 phosphor::logging::entry("SERVICE=%s", service.c_str()),
415 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000416 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700417 }
418
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000419 return ipmi::responseSuccess(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700420}
421
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000422/** @brief implements mdr2 get data info command
423 * @param agentId
424 * @param dataInfo
425 *
426 * @returns IPMI completion code plus response data
427 * - response - mdrVersion, data info, validFlag,
428 * dataLength, dataVersion, timeStamp
429 */
430ipmi::RspType<std::vector<uint8_t>>
431 mdr2GetDataInfo(uint16_t agentId, std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700432{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000433 constexpr size_t getDataInfoReqSize = 16;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700434
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000435 if (dataInfo.size() < getDataInfoReqSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700436 {
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000437 return ipmi::responseReqDataLenInvalid();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700438 }
439
Vernon Mauery15419dd2019-05-24 09:40:30 -0700440 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
441 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700442
443 if (mdrv2 == nullptr)
444 {
445 mdrv2 = std::make_unique<MDRV2>();
446 }
447
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000448 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700449 if (agentIndex == -1)
450 {
451 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000452 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
453 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700454 }
455
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000456 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700457
458 if ((idIndex < 0) || (idIndex >= maxDirEntries))
459 {
460 phosphor::logging::log<phosphor::logging::level::ERR>(
461 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000462 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700463 }
464
Vernon Mauery15419dd2019-05-24 09:40:30 -0700465 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700466 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
467
jayaprakash Mutyala04a38ed2020-05-29 01:42:26 +0000468 method.append(static_cast<uint8_t>(idIndex));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700469
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000470 std::vector<uint8_t> res;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700471 try
472 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700473 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700474 reply.read(res);
475 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700476 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700477 {
478 phosphor::logging::log<phosphor::logging::level::ERR>(
479 "Error get data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700480 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700481 phosphor::logging::entry("SERVICE=%s", service.c_str()),
482 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000483 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700484 }
485
486 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
487 {
488 phosphor::logging::log<phosphor::logging::level::ERR>(
489 "Get data info response length not invalid");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000490 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700491 }
Vernon Mauerya3702c12019-05-22 13:20:59 -0700492
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000493 return ipmi::responseSuccess(res);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700494}
495
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000496/** @brief implements mdr2 data info offer command
497 * @param agentId - Offer a agent ID to get the "Data Set ID"
498 *
499 * @returns IPMI completion code plus response data
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000500 * - dataOut - data Set Id
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000501 */
502ipmi::RspType<std::vector<uint8_t>> mdr2DataInfoOffer(uint16_t agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700503{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700504 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
505 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700506
507 if (mdrv2 == nullptr)
508 {
509 mdrv2 = std::make_unique<MDRV2>();
510 }
511
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000512 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700513 if (agentIndex == -1)
514 {
515 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000516 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
517 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700518 }
519
Vernon Mauery15419dd2019-05-24 09:40:30 -0700520 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700521 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
522
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000523 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700524 try
525 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700526 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000527 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700528 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700529 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700530 {
531 phosphor::logging::log<phosphor::logging::level::ERR>(
532 "Error send data info offer",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700533 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700534 phosphor::logging::entry("SERVICE=%s", service.c_str()),
535 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000536 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700537 }
538
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000539 constexpr size_t respInfoSize = 16;
540 if (dataOut.size() != respInfoSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700541 {
542 phosphor::logging::log<phosphor::logging::level::ERR>(
543 "Error send data info offer, return length invalid");
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000544 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700545 }
546
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000547 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700548}
549
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000550/** @brief implements mdr2 send data info command
551 * @param agentId
552 * @param dataInfo
553 * @param validFlag
554 * @param dataLength
555 * @param dataVersion
556 * @param timeStamp
557 *
558 * @returns IPMI completion code plus response data
559 * - bool
560 */
561ipmi::RspType<bool> mdr2SendDataInfo(uint16_t agentId,
562 std::array<uint8_t, dataInfoSize> dataInfo,
563 uint8_t validFlag, uint32_t dataLength,
564 uint32_t dataVersion, uint32_t timeStamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700565{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000566 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700567 {
568 phosphor::logging::log<phosphor::logging::level::ERR>(
569 "Requested data length is out of SMBIOS Table storage size.");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000570 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700571 }
572
Vernon Mauery15419dd2019-05-24 09:40:30 -0700573 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
574 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700575
576 if (mdrv2 == nullptr)
577 {
578 mdrv2 = std::make_unique<MDRV2>();
579 }
580
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000581 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700582 if (agentIndex == -1)
583 {
584 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000585 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
586 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700587 }
588
Patrick Venture6d765602019-09-25 17:11:07 -0700589 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700590
591 if ((idIndex < 0) || (idIndex >= maxDirEntries))
592 {
593 phosphor::logging::log<phosphor::logging::level::ERR>(
594 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000595 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700596 }
597
Vernon Mauery15419dd2019-05-24 09:40:30 -0700598 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700599 service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
600
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000601 method.append((uint8_t)idIndex, validFlag, dataLength, dataVersion,
602 timeStamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700603
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000604 bool entryChanged = true;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700605 try
606 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700607 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700608 reply.read(entryChanged);
609 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700610 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700611 {
612 phosphor::logging::log<phosphor::logging::level::ERR>(
613 "Error send data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700614 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700615 phosphor::logging::entry("SERVICE=%s", service.c_str()),
616 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000617 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700618 }
619
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000620 return ipmi::responseSuccess(entryChanged);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700621}
622
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000623/**
624@brief This command is MDR related get data block command.
625
626@param - agentId
627@param - lockHandle
628@param - xferOffset
629@param - xferLength
630
631@return on success
632 - xferLength
633 - checksum
634 - data
635**/
636ipmi::RspType<uint32_t, // xferLength
637 uint32_t, // Checksum
638 std::vector<uint8_t> // data
639 >
640 mdr2GetDataBlock(uint16_t agentId, uint16_t lockHandle, uint32_t xferOffset,
641 uint32_t xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700642{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700643 if (mdrv2 == nullptr)
644 {
645 mdrv2 = std::make_unique<MDRV2>();
646 }
647
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000648 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700649 if (agentIndex == -1)
650 {
651 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000652 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
653 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700654 }
655
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000656 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700657
658 if ((idIndex < 0) || (idIndex >= maxDirEntries))
659 {
660 phosphor::logging::log<phosphor::logging::level::ERR>(
661 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000662 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700663 }
664
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000665 if (xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700666 {
667 phosphor::logging::log<phosphor::logging::level::ERR>(
668 "Offset is outside of range.");
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 size_t outSize = (xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
673 ? mdrv2->smbiosDir.dir[idIndex].xferSize
674 : xferLength;
675 if (outSize > UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700676 {
677 phosphor::logging::log<phosphor::logging::level::ERR>(
678 "Out size and offset are out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000679 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700680 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000681 if ((xferOffset + outSize) > mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700682 {
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000683 outSize = mdrv2->smbiosDir.dir[idIndex].common.size - xferOffset;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700684 }
685
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000686 uint32_t respXferLength = outSize;
687
688 if (respXferLength > xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700689 {
690 phosphor::logging::log<phosphor::logging::level::ERR>(
691 "Get data block unexpected error.");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000692 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700693 }
694
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000695 if ((xferOffset + outSize) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700696 UINT_MAX -
697 reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
698 {
699 phosphor::logging::log<phosphor::logging::level::ERR>(
700 "Input data to calculate checksum is out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000701 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700702 }
703
704 uint32_t u32Checksum = mdrv2->calcChecksum32(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000705 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset, outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700706 if (u32Checksum == invalidChecksum)
707 {
708 phosphor::logging::log<phosphor::logging::level::ERR>(
709 "Get data block failed - invalid checksum");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000710 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700711 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000712 std::vector<uint8_t> data(outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700713
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000714 std::copy(&mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset],
715 &mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset + outSize],
716 data.begin());
Vernon Mauerya3702c12019-05-22 13:20:59 -0700717
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000718 return ipmi::responseSuccess(respXferLength, u32Checksum, data);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700719}
720
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000721/** @brief implements mdr2 send data block command
722 * @param agentId
723 * @param lockHandle
724 * @param xferOffset
725 * @param xferLength
726 * @param checksum
727 *
728 * @returns IPMI completion code
729 */
730ipmi::RspType<> mdr2SendDataBlock(uint16_t agentId, uint16_t lockHandle,
731 uint32_t xferOffset, uint32_t xferLength,
732 uint32_t checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700733{
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000734
Vernon Mauerya3702c12019-05-22 13:20:59 -0700735 if (mdrv2 == nullptr)
736 {
737 mdrv2 = std::make_unique<MDRV2>();
738 }
739
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000740 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700741 if (agentIndex == -1)
742 {
743 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000744 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
745 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700746 }
747
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000748 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700749
750 if ((idIndex < 0) || (idIndex >= maxDirEntries))
751 {
752 phosphor::logging::log<phosphor::logging::level::ERR>(
753 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000754 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700755 }
756
757 if (mdrv2->smbiosIsUpdating(idIndex))
758 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000759 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700760 {
761 phosphor::logging::log<phosphor::logging::level::ERR>(
762 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000763 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700764 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000765 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700766 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000767 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700768 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
769 {
770 phosphor::logging::log<phosphor::logging::level::ERR>(
771 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000772 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700773 }
774 if (reinterpret_cast<size_t>(
775 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000776 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700777 {
778 phosphor::logging::log<phosphor::logging::level::ERR>(
779 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000780 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700781 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700782 uint8_t* destAddr =
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000783 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset;
James Feistfcd2d3a2020-05-28 10:38:15 -0700784 uint8_t* sourceAddr = reinterpret_cast<uint8_t*>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000785 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
786 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700787 {
788 phosphor::logging::log<phosphor::logging::level::ERR>(
789 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000790 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700791 }
792 else
793 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000794 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700795 {
796 phosphor::logging::log<phosphor::logging::level::ERR>(
797 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000798 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700799 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000800 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700801 }
802 }
803 else
804 {
805 phosphor::logging::log<phosphor::logging::level::ERR>(
806 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000807 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700808 }
809
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000810 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700811}
812
James Feistfcd2d3a2020-05-28 10:38:15 -0700813bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700814{
815 std::ofstream smbiosFile(mdrType2File,
816 std::ios_base::binary | std::ios_base::trunc);
817 if (!smbiosFile.good())
818 {
819 phosphor::logging::log<phosphor::logging::level::ERR>(
820 "Write data from flash error - Open MDRV2 table file failure");
821 return false;
822 }
823
824 try
825 {
James Feistfcd2d3a2020-05-28 10:38:15 -0700826 smbiosFile.write(reinterpret_cast<char*>(mdrHdr),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700827 sizeof(MDRSMBIOSHeader));
James Feistfcd2d3a2020-05-28 10:38:15 -0700828 smbiosFile.write(reinterpret_cast<char*>(data), mdrHdr->dataSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700829 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700830 catch (std::ofstream::failure& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700831 {
832 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700833 "Write data from flash error - write data error",
834 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700835 return false;
836 }
837
838 return true;
839}
840
841void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
842{
843 int memDriver = 0;
844
845 // open mem driver for the system memory access
846 memDriver = open("/dev/vgasharedmem", O_RDONLY);
847 if (memDriver < 0)
848 {
849 phosphor::logging::log<phosphor::logging::level::ERR>(
850 "Cannot access mem driver");
851 throw std::system_error(EIO, std::generic_category());
852 }
853
854 // map the system memory
855 vPtr = mmap(NULL, // where to map to: don't mind
856 areaSize, // how many bytes ?
857 PROT_READ, // want to read and write
858 MAP_SHARED, // no copy on write
859 memDriver, // handle to /dev/mem
860 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
861
862 close(memDriver);
863 if (vPtr == MAP_FAILED)
864 {
865 phosphor::logging::log<phosphor::logging::level::ERR>(
866 "Failed to map share memory");
867 throw std::system_error(EIO, std::generic_category());
868 }
869 size = areaSize;
870 physicalAddr = addr;
871}
872
873bool MDRV2::smbiosUnlock(uint8_t index)
874{
P Dheeraj Srujan Kumar36ed8d22021-08-04 01:14:14 +0530875 bool ret = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700876 switch (smbiosDir.dir[index].stage)
877 {
878 case MDR2SMBIOSStatusEnum::mdr2Updating:
879 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
880 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
881
882 timer->stop();
883 smbiosDir.dir[index].lockHandle = 0;
884 ret = true;
885 break;
886
887 case MDR2SMBIOSStatusEnum::mdr2Updated:
888 case MDR2SMBIOSStatusEnum::mdr2Loaded:
889 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
890
891 timer->stop();
892
893 smbiosDir.dir[index].lockHandle = 0;
894 ret = true;
895 break;
896
897 default:
898 break;
899 }
900
901 return ret;
902}
903
James Feistfcd2d3a2020-05-28 10:38:15 -0700904bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700905 uint16_t timeout)
906{
907 bool ret = false;
908 uint32_t u32Status = 0;
909
910 if (timeout == 0)
911 {
912 timeout = defaultTimeout;
913 }
914 std::chrono::microseconds usec(timeout * sysClock);
915
916 switch (smbiosDir.dir[index].stage)
917 {
918 case MDR2SMBIOSStatusEnum::mdr2Updating:
919 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
920 {
921 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
922 timer->start(usec);
923 lockIndex = index;
924
925 *session = getSessionHandle(&smbiosDir);
926 smbiosDir.dir[index].lockHandle = *session;
927 ret = true;
928 }
929 break;
930 case MDR2SMBIOSStatusEnum::mdr2Init:
931 if (flag)
932 {
933 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
934 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
935 timer->start(usec);
936 lockIndex = index;
937
938 *session = getSessionHandle(&smbiosDir);
939 smbiosDir.dir[index].lockHandle = *session;
940 ret = true;
941 }
942 break;
943
944 case MDR2SMBIOSStatusEnum::mdr2Updated:
945 case MDR2SMBIOSStatusEnum::mdr2Loaded:
946 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
947 {
948 if (flag)
949 {
950 smbiosDir.dir[index].stage =
951 MDR2SMBIOSStatusEnum::mdr2Updating;
952 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
953 }
954 else
955 {
956 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
957 }
958
959 timer->start(usec);
960 lockIndex = index;
961
962 *session = getSessionHandle(&smbiosDir);
963 smbiosDir.dir[index].lockHandle = *session;
964 ret = true;
965 }
966 break;
967
968 default:
969 break;
970 }
971 return ret;
972}
973
974void MDRV2::timeoutHandler()
975{
976 smbiosUnlock(lockIndex);
977 mdrv2->area.reset(nullptr);
978}
979
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000980/** @brief implements mdr2 lock data command
981 * @param agentId
982 * @param dataInfo
983 * @param timeout
984 *
985 * @returns IPMI completion code plus response data
986 * - mdr2Version
987 * - session
988 * - dataLength
989 * - xferAddress
990 * - xferLength
991 */
992ipmi::RspType<uint8_t, // mdr2Version
993 uint16_t, // session
994 uint32_t, // dataLength
995 uint32_t, // xferAddress
996 uint32_t // xferLength
997 >
998 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
999 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001000{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001001 if (mdrv2 == nullptr)
1002 {
1003 mdrv2 = std::make_unique<MDRV2>();
1004 }
1005
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001006 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001007 if (agentIndex == -1)
1008 {
1009 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001010 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1011 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001012 }
1013
Vernon Mauery15419dd2019-05-24 09:40:30 -07001014 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1015 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001016
Patrick Venture6d765602019-09-25 17:11:07 -07001017 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001018
1019 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1020 {
1021 phosphor::logging::log<phosphor::logging::level::ERR>(
1022 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001023 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001024 }
1025
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001026 uint16_t session = 0;
1027 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001028 {
1029 phosphor::logging::log<phosphor::logging::level::ERR>(
1030 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001031 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001032 }
1033
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001034 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1035 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1036 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001037
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001038 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1039 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001040}
1041
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001042/** @brief implements mdr2 unlock data command
1043 * @param agentId
1044 * @param lockHandle
1045 *
1046 * @returns IPMI completion code
1047 */
1048ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001049{
1050 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001051
Vernon Mauerya3702c12019-05-22 13:20:59 -07001052 if (mdrv2 == nullptr)
1053 {
1054 mdrv2 = std::make_unique<MDRV2>();
1055 }
1056
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001057 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001058 if (agentIndex == -1)
1059 {
1060 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001061 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1062 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001063 }
1064
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001065 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001066
1067 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1068 {
1069 phosphor::logging::log<phosphor::logging::level::ERR>(
1070 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001071 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001072 }
1073
1074 if (!mdrv2->smbiosUnlock(idIndex))
1075 {
1076 phosphor::logging::log<phosphor::logging::level::ERR>(
1077 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001078 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001079 }
1080
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001081 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001082}
1083
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001084/**
1085@brief This command is executed after POST BIOS to get the session info.
1086
1087@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1088
1089@return xferStartAck and session on success.
1090**/
1091ipmi::RspType<uint8_t, uint16_t>
1092 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1093 uint32_t dataLength, uint32_t xferAddress,
1094 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001095{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001096 uint16_t session = 0;
1097
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001098 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001099 {
1100 phosphor::logging::log<phosphor::logging::level::ERR>(
1101 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001102 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001103 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001104 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001105 {
1106 phosphor::logging::log<phosphor::logging::level::ERR>(
1107 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001108 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001109 }
1110
Vernon Mauery15419dd2019-05-24 09:40:30 -07001111 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1112 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001113
1114 if (mdrv2 == nullptr)
1115 {
1116 mdrv2 = std::make_unique<MDRV2>();
1117 }
1118
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001119 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001120 if (agentIndex == -1)
1121 {
1122 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001123 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1124 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001125 }
1126
Patrick Venture6d765602019-09-25 17:11:07 -07001127 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001128
1129 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1130 {
1131 phosphor::logging::log<phosphor::logging::level::ERR>(
1132 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001133 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001134 }
1135
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001136 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001137 {
1138 try
1139 {
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001140 mdrv2->area =
1141 std::make_unique<SharedMemoryArea>(xferAddress, xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001142 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001143 catch (const std::system_error& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001144 {
1145 mdrv2->smbiosUnlock(idIndex);
1146 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001147 "Unable to access share memory",
1148 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001149 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001150 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001151 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001152 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1153 if (-1 ==
1154 mdrv2->syncDirCommonData(
1155 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1156 {
1157 phosphor::logging::log<phosphor::logging::level::ERR>(
1158 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001159 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001160 }
1161 }
1162 else
1163 {
1164 phosphor::logging::log<phosphor::logging::level::ERR>(
1165 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001166 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001167 }
1168
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001169 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001170
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001171 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001172}
1173
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001174/**
1175@brief This command is executed to close the session.
1176
1177@param - agentId, lockHandle.
1178
1179@return completion code on success.
1180**/
1181ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001182{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001183
1184 if (mdrv2 == nullptr)
1185 {
1186 mdrv2 = std::make_unique<MDRV2>();
1187 }
1188
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001189 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001190 if (agentIndex == -1)
1191 {
1192 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001193 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1194 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001195 }
1196
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001197 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001198
1199 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1200 {
1201 phosphor::logging::log<phosphor::logging::level::ERR>(
1202 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001203 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001204 }
1205
1206 if (!mdrv2->smbiosUnlock(idIndex))
1207 {
1208 phosphor::logging::log<phosphor::logging::level::ERR>(
1209 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001210 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001211 }
1212
1213 mdrv2->area.reset(nullptr);
1214 MDRSMBIOSHeader mdr2Smbios;
1215 mdr2Smbios.mdrType = mdrTypeII;
1216 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1217 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1218 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1219
1220 if (access(smbiosPath, 0) == -1)
1221 {
1222 int flag = mkdir(smbiosPath, S_IRWXU);
1223 if (flag != 0)
1224 {
1225 phosphor::logging::log<phosphor::logging::level::ERR>(
1226 "create folder failed for writting smbios file");
1227 }
1228 }
1229 if (!mdrv2->storeDatatoFlash(
1230 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1231 {
1232 phosphor::logging::log<phosphor::logging::level::ERR>(
1233 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001234 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001235 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001236 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001237 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1238 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
1239 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001240 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1241
1242 try
1243 {
Vernon Mauery15419dd2019-05-24 09:40:30 -07001244 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001245 reply.read(status);
1246 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001247 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001248 {
1249 phosphor::logging::log<phosphor::logging::level::ERR>(
1250 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001251 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001252 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1253 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001254 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001255 }
1256
1257 if (!status)
1258 {
1259 phosphor::logging::log<phosphor::logging::level::ERR>(
1260 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001261 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001262 }
1263
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001264 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001265}
1266
1267static void register_netfn_smbiosmdrv2_functions(void)
1268{
1269 // MDR V2 Command
1270 // <Get MDRII Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001271 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1272 ipmi::intel::app::cmdMdrIIAgentStatus,
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001273 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001274
1275 // <Get MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001276 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1277 ipmi::intel::app::cmdMdrIIGetDir,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001278 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001279
1280 // <Send MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001281 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1282 ipmi::intel::app::cmdMdrIISendDir,
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001283 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001284
1285 // <Get MDRII Data Info Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001286 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1287 ipmi::intel::app::cmdMdrIIGetDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001288 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001289
1290 // <Send MDRII Info Offer>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001291 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1292 ipmi::intel::app::cmdMdrIISendDataInfoOffer,
1293 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001294
1295 // <Send MDRII Data Info>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001296 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1297 ipmi::intel::app::cmdMdrIISendDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001298 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001299
1300 // <Get MDRII Data Block Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001301 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1302 ipmi::intel::app::cmdMdrIIGetDataBlock,
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +00001303 ipmi::Privilege::Operator, mdr2GetDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001304
1305 // <Send MDRII Data Block>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001306 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1307 ipmi::intel::app::cmdMdrIISendDataBlock,
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001308 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001309
1310 // <Lock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001311 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1312 ipmi::intel::app::cmdMdrIILockData,
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001313 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001314
1315 // <Unlock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001316 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1317 ipmi::intel::app::cmdMdrIIUnlockData,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001318 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001319
1320 // <Send MDRII Data Start>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001321 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1322 ipmi::intel::app::cmdMdrIIDataStart,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001323 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001324
1325 // <Send MDRII Data Done>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001326 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1327 ipmi::intel::app::cmdMdrIIDataDone,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001328 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001329}