blob: e0d1159b36f090251df4653e08df482ab635979b [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{
197 if (index > maxDirEntries)
198 {
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 Mutyala7cb59cc2019-06-19 19:17:43 +0000351ipmi::RspType<bool> mdr2SendDir(uint16_t agentId, uint8_t dirVersion,
352 uint8_t dirIndex, uint8_t returnedEntries,
353 uint8_t remainingEntries,
354 std::array<uint8_t, 16> dataInfo, uint32_t size,
355 uint32_t dataSetSize, uint32_t dataVersion,
356 uint32_t timestamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700357{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700358 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
359 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700360
361 if (mdrv2 == nullptr)
362 {
363 mdrv2 = std::make_unique<MDRV2>();
364 }
365
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000366 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700367 if (agentIndex == -1)
368 {
369 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000370 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
371 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700372 }
373
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000374 if ((dirIndex + returnedEntries) > maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700375 {
376 phosphor::logging::log<phosphor::logging::level::ERR>(
377 "Too many directory entries");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000378 return ipmi::response(ccStorageLeak);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700379 }
380
Vernon Mauery15419dd2019-05-24 09:40:30 -0700381 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700382 service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000383 method.append(dirVersion, dirIndex, returnedEntries, remainingEntries,
384 dataInfo, size, dataSetSize, dataVersion, timestamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000386 bool terminate = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700387 try
388 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700389 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000390 reply.read(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700391 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700392 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700393 {
394 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700395 "Error send dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700396 phosphor::logging::entry("SERVICE=%s", service.c_str()),
397 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000398 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700399 }
400
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000401 return ipmi::responseSuccess(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700402}
403
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000404/** @brief implements mdr2 get data info command
405 * @param agentId
406 * @param dataInfo
407 *
408 * @returns IPMI completion code plus response data
409 * - response - mdrVersion, data info, validFlag,
410 * dataLength, dataVersion, timeStamp
411 */
412ipmi::RspType<std::vector<uint8_t>>
413 mdr2GetDataInfo(uint16_t agentId, std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700414{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000415 constexpr size_t getDataInfoReqSize = 16;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700416
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000417 if (dataInfo.size() < getDataInfoReqSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700418 {
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000419 return ipmi::responseReqDataLenInvalid();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700420 }
421
Vernon Mauery15419dd2019-05-24 09:40:30 -0700422 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
423 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700424
425 if (mdrv2 == nullptr)
426 {
427 mdrv2 = std::make_unique<MDRV2>();
428 }
429
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000430 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700431 if (agentIndex == -1)
432 {
433 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000434 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
435 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700436 }
437
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000438 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700439
440 if ((idIndex < 0) || (idIndex >= maxDirEntries))
441 {
442 phosphor::logging::log<phosphor::logging::level::ERR>(
443 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000444 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700445 }
446
Vernon Mauery15419dd2019-05-24 09:40:30 -0700447 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700448 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
449
jayaprakash Mutyala04a38ed2020-05-29 01:42:26 +0000450 method.append(static_cast<uint8_t>(idIndex));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700451
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000452 std::vector<uint8_t> res;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700453 try
454 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700455 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700456 reply.read(res);
457 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700458 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700459 {
460 phosphor::logging::log<phosphor::logging::level::ERR>(
461 "Error get data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700462 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700463 phosphor::logging::entry("SERVICE=%s", service.c_str()),
464 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000465 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700466 }
467
468 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
469 {
470 phosphor::logging::log<phosphor::logging::level::ERR>(
471 "Get data info response length not invalid");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000472 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700473 }
Vernon Mauerya3702c12019-05-22 13:20:59 -0700474
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000475 return ipmi::responseSuccess(res);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700476}
477
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000478/** @brief implements mdr2 data info offer command
479 * @param agentId - Offer a agent ID to get the "Data Set ID"
480 *
481 * @returns IPMI completion code plus response data
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000482 * - dataOut - data Set Id
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000483 */
484ipmi::RspType<std::vector<uint8_t>> mdr2DataInfoOffer(uint16_t agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700485{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700486 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
487 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700488
489 if (mdrv2 == nullptr)
490 {
491 mdrv2 = std::make_unique<MDRV2>();
492 }
493
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000494 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700495 if (agentIndex == -1)
496 {
497 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000498 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
499 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700500 }
501
Vernon Mauery15419dd2019-05-24 09:40:30 -0700502 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700503 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
504
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000505 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700506 try
507 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700508 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000509 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700510 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700511 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700512 {
513 phosphor::logging::log<phosphor::logging::level::ERR>(
514 "Error send data info offer",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700515 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700516 phosphor::logging::entry("SERVICE=%s", service.c_str()),
517 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000518 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700519 }
520
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000521 constexpr size_t respInfoSize = 16;
522 if (dataOut.size() != respInfoSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700523 {
524 phosphor::logging::log<phosphor::logging::level::ERR>(
525 "Error send data info offer, return length invalid");
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000526 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700527 }
528
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000529 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700530}
531
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000532/** @brief implements mdr2 send data info command
533 * @param agentId
534 * @param dataInfo
535 * @param validFlag
536 * @param dataLength
537 * @param dataVersion
538 * @param timeStamp
539 *
540 * @returns IPMI completion code plus response data
541 * - bool
542 */
543ipmi::RspType<bool> mdr2SendDataInfo(uint16_t agentId,
544 std::array<uint8_t, dataInfoSize> dataInfo,
545 uint8_t validFlag, uint32_t dataLength,
546 uint32_t dataVersion, uint32_t timeStamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700547{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000548 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700549 {
550 phosphor::logging::log<phosphor::logging::level::ERR>(
551 "Requested data length is out of SMBIOS Table storage size.");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000552 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700553 }
554
Vernon Mauery15419dd2019-05-24 09:40:30 -0700555 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
556 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700557
558 if (mdrv2 == nullptr)
559 {
560 mdrv2 = std::make_unique<MDRV2>();
561 }
562
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000563 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700564 if (agentIndex == -1)
565 {
566 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000567 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
568 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700569 }
570
Patrick Venture6d765602019-09-25 17:11:07 -0700571 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700572
573 if ((idIndex < 0) || (idIndex >= maxDirEntries))
574 {
575 phosphor::logging::log<phosphor::logging::level::ERR>(
576 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
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 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700581 service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
582
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000583 method.append((uint8_t)idIndex, validFlag, dataLength, dataVersion,
584 timeStamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700585
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000586 bool entryChanged = true;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700587 try
588 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700589 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700590 reply.read(entryChanged);
591 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700592 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700593 {
594 phosphor::logging::log<phosphor::logging::level::ERR>(
595 "Error send data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700596 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700597 phosphor::logging::entry("SERVICE=%s", service.c_str()),
598 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000599 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700600 }
601
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000602 return ipmi::responseSuccess(entryChanged);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700603}
604
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000605/**
606@brief This command is MDR related get data block command.
607
608@param - agentId
609@param - lockHandle
610@param - xferOffset
611@param - xferLength
612
613@return on success
614 - xferLength
615 - checksum
616 - data
617**/
618ipmi::RspType<uint32_t, // xferLength
619 uint32_t, // Checksum
620 std::vector<uint8_t> // data
621 >
622 mdr2GetDataBlock(uint16_t agentId, uint16_t lockHandle, uint32_t xferOffset,
623 uint32_t xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700624{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700625 if (mdrv2 == nullptr)
626 {
627 mdrv2 = std::make_unique<MDRV2>();
628 }
629
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000630 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700631 if (agentIndex == -1)
632 {
633 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000634 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
635 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700636 }
637
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000638 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700639
640 if ((idIndex < 0) || (idIndex >= maxDirEntries))
641 {
642 phosphor::logging::log<phosphor::logging::level::ERR>(
643 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000644 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700645 }
646
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000647 if (xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700648 {
649 phosphor::logging::log<phosphor::logging::level::ERR>(
650 "Offset is outside of range.");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000651 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700652 }
653
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000654 size_t outSize = (xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
655 ? mdrv2->smbiosDir.dir[idIndex].xferSize
656 : xferLength;
657 if (outSize > UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700658 {
659 phosphor::logging::log<phosphor::logging::level::ERR>(
660 "Out size and offset are out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000661 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700662 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000663 if ((xferOffset + outSize) > mdrv2->smbiosDir.dir[idIndex].common.size)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700664 {
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000665 outSize = mdrv2->smbiosDir.dir[idIndex].common.size - xferOffset;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700666 }
667
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000668 uint32_t respXferLength = outSize;
669
670 if (respXferLength > xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700671 {
672 phosphor::logging::log<phosphor::logging::level::ERR>(
673 "Get data block unexpected error.");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000674 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700675 }
676
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000677 if ((xferOffset + outSize) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700678 UINT_MAX -
679 reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
680 {
681 phosphor::logging::log<phosphor::logging::level::ERR>(
682 "Input data to calculate checksum is out of range");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000683 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700684 }
685
686 uint32_t u32Checksum = mdrv2->calcChecksum32(
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000687 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset, outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700688 if (u32Checksum == invalidChecksum)
689 {
690 phosphor::logging::log<phosphor::logging::level::ERR>(
691 "Get data block failed - invalid checksum");
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000692 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700693 }
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000694 std::vector<uint8_t> data(outSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700695
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000696 std::copy(&mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset],
697 &mdrv2->smbiosDir.dir[idIndex].dataStorage[xferOffset + outSize],
698 data.begin());
Vernon Mauerya3702c12019-05-22 13:20:59 -0700699
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000700 return ipmi::responseSuccess(respXferLength, u32Checksum, data);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700701}
702
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000703/** @brief implements mdr2 send data block command
704 * @param agentId
705 * @param lockHandle
706 * @param xferOffset
707 * @param xferLength
708 * @param checksum
709 *
710 * @returns IPMI completion code
711 */
712ipmi::RspType<> mdr2SendDataBlock(uint16_t agentId, uint16_t lockHandle,
713 uint32_t xferOffset, uint32_t xferLength,
714 uint32_t checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700715{
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +0000716
Vernon Mauerya3702c12019-05-22 13:20:59 -0700717 if (mdrv2 == nullptr)
718 {
719 mdrv2 = std::make_unique<MDRV2>();
720 }
721
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000722 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700723 if (agentIndex == -1)
724 {
725 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000726 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
727 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700728 }
729
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000730 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700731
732 if ((idIndex < 0) || (idIndex >= maxDirEntries))
733 {
734 phosphor::logging::log<phosphor::logging::level::ERR>(
735 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000736 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700737 }
738
739 if (mdrv2->smbiosIsUpdating(idIndex))
740 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000741 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700742 {
743 phosphor::logging::log<phosphor::logging::level::ERR>(
744 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000745 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700746 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000747 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700748 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000749 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700750 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
751 {
752 phosphor::logging::log<phosphor::logging::level::ERR>(
753 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000754 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700755 }
756 if (reinterpret_cast<size_t>(
757 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000758 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700759 {
760 phosphor::logging::log<phosphor::logging::level::ERR>(
761 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000762 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700763 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700764 uint8_t* destAddr =
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000765 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset;
James Feistfcd2d3a2020-05-28 10:38:15 -0700766 uint8_t* sourceAddr = reinterpret_cast<uint8_t*>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000767 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
768 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700769 {
770 phosphor::logging::log<phosphor::logging::level::ERR>(
771 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000772 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700773 }
774 else
775 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000776 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700777 {
778 phosphor::logging::log<phosphor::logging::level::ERR>(
779 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000780 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700781 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000782 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700783 }
784 }
785 else
786 {
787 phosphor::logging::log<phosphor::logging::level::ERR>(
788 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000789 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700790 }
791
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000792 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700793}
794
James Feistfcd2d3a2020-05-28 10:38:15 -0700795bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700796{
797 std::ofstream smbiosFile(mdrType2File,
798 std::ios_base::binary | std::ios_base::trunc);
799 if (!smbiosFile.good())
800 {
801 phosphor::logging::log<phosphor::logging::level::ERR>(
802 "Write data from flash error - Open MDRV2 table file failure");
803 return false;
804 }
805
806 try
807 {
James Feistfcd2d3a2020-05-28 10:38:15 -0700808 smbiosFile.write(reinterpret_cast<char*>(mdrHdr),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700809 sizeof(MDRSMBIOSHeader));
James Feistfcd2d3a2020-05-28 10:38:15 -0700810 smbiosFile.write(reinterpret_cast<char*>(data), mdrHdr->dataSize);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700811 }
James Feistfcd2d3a2020-05-28 10:38:15 -0700812 catch (std::ofstream::failure& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700813 {
814 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700815 "Write data from flash error - write data error",
816 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700817 return false;
818 }
819
820 return true;
821}
822
823void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
824{
825 int memDriver = 0;
826
827 // open mem driver for the system memory access
828 memDriver = open("/dev/vgasharedmem", O_RDONLY);
829 if (memDriver < 0)
830 {
831 phosphor::logging::log<phosphor::logging::level::ERR>(
832 "Cannot access mem driver");
833 throw std::system_error(EIO, std::generic_category());
834 }
835
836 // map the system memory
837 vPtr = mmap(NULL, // where to map to: don't mind
838 areaSize, // how many bytes ?
839 PROT_READ, // want to read and write
840 MAP_SHARED, // no copy on write
841 memDriver, // handle to /dev/mem
842 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
843
844 close(memDriver);
845 if (vPtr == MAP_FAILED)
846 {
847 phosphor::logging::log<phosphor::logging::level::ERR>(
848 "Failed to map share memory");
849 throw std::system_error(EIO, std::generic_category());
850 }
851 size = areaSize;
852 physicalAddr = addr;
853}
854
855bool MDRV2::smbiosUnlock(uint8_t index)
856{
857 bool ret;
858 switch (smbiosDir.dir[index].stage)
859 {
860 case MDR2SMBIOSStatusEnum::mdr2Updating:
861 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
862 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
863
864 timer->stop();
865 smbiosDir.dir[index].lockHandle = 0;
866 ret = true;
867 break;
868
869 case MDR2SMBIOSStatusEnum::mdr2Updated:
870 case MDR2SMBIOSStatusEnum::mdr2Loaded:
871 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
872
873 timer->stop();
874
875 smbiosDir.dir[index].lockHandle = 0;
876 ret = true;
877 break;
878
879 default:
880 break;
881 }
882
883 return ret;
884}
885
James Feistfcd2d3a2020-05-28 10:38:15 -0700886bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700887 uint16_t timeout)
888{
889 bool ret = false;
890 uint32_t u32Status = 0;
891
892 if (timeout == 0)
893 {
894 timeout = defaultTimeout;
895 }
896 std::chrono::microseconds usec(timeout * sysClock);
897
898 switch (smbiosDir.dir[index].stage)
899 {
900 case MDR2SMBIOSStatusEnum::mdr2Updating:
901 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
902 {
903 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
904 timer->start(usec);
905 lockIndex = index;
906
907 *session = getSessionHandle(&smbiosDir);
908 smbiosDir.dir[index].lockHandle = *session;
909 ret = true;
910 }
911 break;
912 case MDR2SMBIOSStatusEnum::mdr2Init:
913 if (flag)
914 {
915 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
916 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
917 timer->start(usec);
918 lockIndex = index;
919
920 *session = getSessionHandle(&smbiosDir);
921 smbiosDir.dir[index].lockHandle = *session;
922 ret = true;
923 }
924 break;
925
926 case MDR2SMBIOSStatusEnum::mdr2Updated:
927 case MDR2SMBIOSStatusEnum::mdr2Loaded:
928 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
929 {
930 if (flag)
931 {
932 smbiosDir.dir[index].stage =
933 MDR2SMBIOSStatusEnum::mdr2Updating;
934 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
935 }
936 else
937 {
938 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
939 }
940
941 timer->start(usec);
942 lockIndex = index;
943
944 *session = getSessionHandle(&smbiosDir);
945 smbiosDir.dir[index].lockHandle = *session;
946 ret = true;
947 }
948 break;
949
950 default:
951 break;
952 }
953 return ret;
954}
955
956void MDRV2::timeoutHandler()
957{
958 smbiosUnlock(lockIndex);
959 mdrv2->area.reset(nullptr);
960}
961
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000962/** @brief implements mdr2 lock data command
963 * @param agentId
964 * @param dataInfo
965 * @param timeout
966 *
967 * @returns IPMI completion code plus response data
968 * - mdr2Version
969 * - session
970 * - dataLength
971 * - xferAddress
972 * - xferLength
973 */
974ipmi::RspType<uint8_t, // mdr2Version
975 uint16_t, // session
976 uint32_t, // dataLength
977 uint32_t, // xferAddress
978 uint32_t // xferLength
979 >
980 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
981 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700982{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700983 if (mdrv2 == nullptr)
984 {
985 mdrv2 = std::make_unique<MDRV2>();
986 }
987
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000988 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700989 if (agentIndex == -1)
990 {
991 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000992 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
993 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700994 }
995
Vernon Mauery15419dd2019-05-24 09:40:30 -0700996 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
997 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700998
Patrick Venture6d765602019-09-25 17:11:07 -0700999 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001000
1001 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1002 {
1003 phosphor::logging::log<phosphor::logging::level::ERR>(
1004 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001005 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001006 }
1007
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001008 uint16_t session = 0;
1009 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001010 {
1011 phosphor::logging::log<phosphor::logging::level::ERR>(
1012 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001013 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001014 }
1015
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001016 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1017 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1018 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001019
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001020 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1021 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001022}
1023
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001024/** @brief implements mdr2 unlock data command
1025 * @param agentId
1026 * @param lockHandle
1027 *
1028 * @returns IPMI completion code
1029 */
1030ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001031{
1032 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001033
Vernon Mauerya3702c12019-05-22 13:20:59 -07001034 if (mdrv2 == nullptr)
1035 {
1036 mdrv2 = std::make_unique<MDRV2>();
1037 }
1038
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001039 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001040 if (agentIndex == -1)
1041 {
1042 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001043 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1044 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001045 }
1046
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001047 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001048
1049 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1050 {
1051 phosphor::logging::log<phosphor::logging::level::ERR>(
1052 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001053 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001054 }
1055
1056 if (!mdrv2->smbiosUnlock(idIndex))
1057 {
1058 phosphor::logging::log<phosphor::logging::level::ERR>(
1059 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001060 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001061 }
1062
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001063 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001064}
1065
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001066/**
1067@brief This command is executed after POST BIOS to get the session info.
1068
1069@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1070
1071@return xferStartAck and session on success.
1072**/
1073ipmi::RspType<uint8_t, uint16_t>
1074 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1075 uint32_t dataLength, uint32_t xferAddress,
1076 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001077{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001078 uint16_t session = 0;
1079
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001080 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001081 {
1082 phosphor::logging::log<phosphor::logging::level::ERR>(
1083 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001084 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001085 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001086 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001087 {
1088 phosphor::logging::log<phosphor::logging::level::ERR>(
1089 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001090 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001091 }
1092
Vernon Mauery15419dd2019-05-24 09:40:30 -07001093 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1094 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001095
1096 if (mdrv2 == nullptr)
1097 {
1098 mdrv2 = std::make_unique<MDRV2>();
1099 }
1100
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001101 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001102 if (agentIndex == -1)
1103 {
1104 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001105 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1106 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001107 }
1108
Patrick Venture6d765602019-09-25 17:11:07 -07001109 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001110
1111 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1112 {
1113 phosphor::logging::log<phosphor::logging::level::ERR>(
1114 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001115 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001116 }
1117
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001118 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001119 {
1120 try
1121 {
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001122 mdrv2->area =
1123 std::make_unique<SharedMemoryArea>(xferAddress, xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001124 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001125 catch (const std::system_error& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001126 {
1127 mdrv2->smbiosUnlock(idIndex);
1128 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001129 "Unable to access share memory",
1130 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001131 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001132 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001133 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001134 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1135 if (-1 ==
1136 mdrv2->syncDirCommonData(
1137 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1138 {
1139 phosphor::logging::log<phosphor::logging::level::ERR>(
1140 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001141 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001142 }
1143 }
1144 else
1145 {
1146 phosphor::logging::log<phosphor::logging::level::ERR>(
1147 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001148 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001149 }
1150
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001151 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001152
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001153 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001154}
1155
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001156/**
1157@brief This command is executed to close the session.
1158
1159@param - agentId, lockHandle.
1160
1161@return completion code on success.
1162**/
1163ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001164{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001165
1166 if (mdrv2 == nullptr)
1167 {
1168 mdrv2 = std::make_unique<MDRV2>();
1169 }
1170
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001171 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001172 if (agentIndex == -1)
1173 {
1174 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001175 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1176 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001177 }
1178
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001179 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001180
1181 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1182 {
1183 phosphor::logging::log<phosphor::logging::level::ERR>(
1184 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001185 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001186 }
1187
1188 if (!mdrv2->smbiosUnlock(idIndex))
1189 {
1190 phosphor::logging::log<phosphor::logging::level::ERR>(
1191 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001192 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001193 }
1194
1195 mdrv2->area.reset(nullptr);
1196 MDRSMBIOSHeader mdr2Smbios;
1197 mdr2Smbios.mdrType = mdrTypeII;
1198 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1199 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1200 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1201
1202 if (access(smbiosPath, 0) == -1)
1203 {
1204 int flag = mkdir(smbiosPath, S_IRWXU);
1205 if (flag != 0)
1206 {
1207 phosphor::logging::log<phosphor::logging::level::ERR>(
1208 "create folder failed for writting smbios file");
1209 }
1210 }
1211 if (!mdrv2->storeDatatoFlash(
1212 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1213 {
1214 phosphor::logging::log<phosphor::logging::level::ERR>(
1215 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001216 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001217 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001218 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001219 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1220 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
1221 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001222 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1223
1224 try
1225 {
Vernon Mauery15419dd2019-05-24 09:40:30 -07001226 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001227 reply.read(status);
1228 }
James Feistfcd2d3a2020-05-28 10:38:15 -07001229 catch (sdbusplus::exception_t& e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001230 {
1231 phosphor::logging::log<phosphor::logging::level::ERR>(
1232 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001233 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001234 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1235 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001236 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001237 }
1238
1239 if (!status)
1240 {
1241 phosphor::logging::log<phosphor::logging::level::ERR>(
1242 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001243 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001244 }
1245
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001246 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001247}
1248
1249static void register_netfn_smbiosmdrv2_functions(void)
1250{
1251 // MDR V2 Command
1252 // <Get MDRII Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001253 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1254 ipmi::intel::app::cmdMdrIIAgentStatus,
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001255 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001256
1257 // <Get MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001258 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1259 ipmi::intel::app::cmdMdrIIGetDir,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001260 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001261
1262 // <Send MDRII Directory Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001263 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1264 ipmi::intel::app::cmdMdrIISendDir,
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001265 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001266
1267 // <Get MDRII Data Info Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001268 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1269 ipmi::intel::app::cmdMdrIIGetDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001270 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001271
1272 // <Send MDRII Info Offer>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001273 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1274 ipmi::intel::app::cmdMdrIISendDataInfoOffer,
1275 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001276
1277 // <Send MDRII Data Info>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001278 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1279 ipmi::intel::app::cmdMdrIISendDataInfo,
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001280 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001281
1282 // <Get MDRII Data Block Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001283 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1284 ipmi::intel::app::cmdMdrIIGetDataBlock,
Deepak Kumar Sahuf4f5c162019-06-11 17:45:05 +00001285 ipmi::Privilege::Operator, mdr2GetDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001286
1287 // <Send MDRII Data Block>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001288 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1289 ipmi::intel::app::cmdMdrIISendDataBlock,
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001290 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001291
1292 // <Lock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001293 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1294 ipmi::intel::app::cmdMdrIILockData,
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001295 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001296
1297 // <Unlock MDRII Data Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001298 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1299 ipmi::intel::app::cmdMdrIIUnlockData,
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001300 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001301
1302 // <Send MDRII Data Start>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001303 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1304 ipmi::intel::app::cmdMdrIIDataStart,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001305 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001306
1307 // <Send MDRII Data Done>
Vernon Mauery98bbf692019-09-16 11:14:59 -07001308 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
1309 ipmi::intel::app::cmdMdrIIDataDone,
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001310 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001311}