blob: a1ada8e713cb323ebfa64fdeca53f93b0a2741b2 [file] [log] [blame]
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001/*
2// Copyright (c) 2020 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
Arun Lal K Me7725612021-07-15 18:20:58 +000017#include "biosxml.hpp"
18
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080019#include <openssl/sha.h>
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080020
21#include <biosconfigcommands.hpp>
22#include <boost/crc.hpp>
23#include <boost/process/child.hpp>
24#include <boost/process/io.hpp>
25#include <ipmid/api.hpp>
26#include <ipmid/message.hpp>
27#include <ipmid/message/types.hpp>
28#include <ipmid/types.hpp>
29#include <ipmid/utils.hpp>
30#include <nlohmann/json.hpp>
31#include <oemcommands.hpp>
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080032#include <sdbusplus/bus.hpp>
33#include <sdbusplus/message/types.hpp>
34
35#include <filesystem>
Suryakanth Sekarcc402592021-04-01 15:02:10 +053036#include <string_view>
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080037
38namespace ipmi
39{
Arun Lal K Mb0caca02021-09-05 22:09:33 +000040static bool flushNVOOBdata();
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080041static void registerBIOSConfigFunctions() __attribute__((constructor));
42
43// Define BIOS config related Completion Code
44using Cc = uint8_t;
45static constexpr Cc ipmiCCPayloadPayloadPacketMissed = 0x80;
46static constexpr Cc ipmiCCBIOSPasswordInitNotDone = 0x80;
47static constexpr Cc ipmiCCPayloadChecksumFailed = 0x81;
48static constexpr Cc ipmiCCNotSupportedInCurrentState = 0x82;
49static constexpr Cc ipmiCCPayloadPayloadInComplete = 0x83;
50static constexpr Cc ipmiCCBIOSCapabilityInitNotDone = 0x85;
51static constexpr Cc ipmiCCPayloadLengthIllegal = 0x85;
52
53static constexpr uint8_t userPasswordChanged = (1 << 5);
54static constexpr uint8_t adminPasswordChanged = (1 << 4);
55
56static constexpr const char* biosConfigFolder = "/var/oob";
57static constexpr const char* biosConfigNVPath = "/var/oob/nvoobdata.dat";
58static constexpr const uint8_t algoSHA384 = 2;
Ayushi Smriti32381872021-06-23 11:05:48 +053059static constexpr const uint8_t algoSHA256 = 1;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080060static constexpr const uint8_t biosCapOffsetBit = 0x3;
61static constexpr uint16_t maxGetPayloadDataSize = 4096;
62static constexpr const char* biosXMLFilePath = "/var/oob/bios.xml";
63static constexpr const char* biosXMLFilePath1 = "/var/oob/tempbios.xml";
64
65static constexpr const char* biosConfigBaseMgrPath =
66 "/xyz/openbmc_project/bios_config/manager";
67static constexpr const char* biosConfigIntf =
68 "xyz.openbmc_project.BIOSConfig.Manager";
69static constexpr const char* resetBIOSSettingsProp = "ResetBIOSSettings";
70/*baseBIOSTable
71map{attributeName,struct{attributeType,readonlyStatus,displayname,
72 description,menuPath,current,default,
73 array{struct{optionstring,optionvalue}}}}
74*/
Arun Lal K Me7725612021-07-15 18:20:58 +000075
76bios::BiosBaseTableType attributesData;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +080077
78NVOOBdata gNVOOBdata;
79
80enum class PTState : uint8_t
81{
82 StartTransfer = 0,
83 InProgress = 1,
84 EndTransfer = 2,
85 UserAbort = 3
86};
87enum class PStatus : uint8_t
88{
89 Unknown = 0,
90 Valid = 1,
91 Corrupted = 2
92};
93enum class PType : uint8_t
94{
95 IntelXMLType0 = 0,
96 IntelXMLType1 = 1,
97 OTAPayload = 5,
98};
99
100//
101// GetPayload Payload status enumeration
102//
103enum class GetPayloadParameter : uint8_t
104{
105 GetPayloadInfo = 0, // 0
106 GetPayloadData = 1, // 1
107 GetPayloadStatus = 2
108};
109
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000110namespace payload1
111{
112
113enum class AttributesType : uint8_t
114{
115 unknown = 0,
116 string,
117 integer
118};
119
120using PendingAttributesType =
121 std::map<std::string,
122 std::tuple<std::string, std::variant<int64_t, std::string>>>;
123
124AttributesType getAttrType(const std::string_view typeDbus)
125{
126 if (typeDbus == "xyz.openbmc_project.BIOSConfig.Manager."
127 "AttributeType.String")
128 {
129 return AttributesType::string;
130 }
131 else if (typeDbus == "xyz.openbmc_project.BIOSConfig."
132 "Manager.AttributeType.Integer")
133 {
134 return AttributesType::integer;
135 }
136
137 return AttributesType::unknown;
138}
139
140bool fillPayloadData(std::string& payloadData,
141 const std::variant<int64_t, std::string>& attributes,
142 const std::string_view key, AttributesType& attrType)
143{
144 payloadData += key;
145 payloadData += '=';
146
147 if (attrType == AttributesType::string)
148 {
149 if (!std::holds_alternative<std::string>(attributes))
150 {
151 phosphor::logging::log<phosphor::logging::level::ERR>(
152 "fillPayloadData: No string data in attributes");
153 return false;
154 }
155 payloadData += std::get<std::string>(attributes);
156 }
157 else if (attrType == AttributesType::integer)
158 {
159 if (!std::holds_alternative<int64_t>(attributes))
160 {
161 phosphor::logging::log<phosphor::logging::level::ERR>(
162 "fillPayloadData: No int64_t data in attributes");
163 return false;
164 }
165 payloadData += std::to_string(std::get<int64_t>(attributes));
166 }
167 else
168 {
169 phosphor::logging::log<phosphor::logging::level::ERR>(
170 "fillPayloadData: Unsupported attribute type");
171 return false;
172 }
173
174 payloadData += '\n';
175
176 return true;
177}
178
179bool getPendingList(ipmi::Context::ptr ctx, std::string& payloadData)
180{
181 std::variant<PendingAttributesType> pendingAttributesData;
182 boost::system::error_code ec;
183
184 payloadData.clear();
185
186 auto dbus = getSdBus();
187 if (!dbus)
188 {
189 phosphor::logging::log<phosphor::logging::level::ERR>(
190 "getPendingList: getSdBus() failed");
191 return false;
192 }
193
194 std::string service =
195 getService(*dbus, biosConfigIntf, biosConfigBaseMgrPath);
196
197 try
198 {
199 pendingAttributesData =
200 dbus->yield_method_call<std::variant<PendingAttributesType>>(
201 ctx->yield, ec, service,
202 "/xyz/openbmc_project/bios_config/manager",
203 "org.freedesktop.DBus.Properties", "Get",
204 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes");
205 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500206 catch (const std::exception& ex)
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000207 {
208 phosphor::logging::log<phosphor::logging::level::ERR>(ex.what());
209 return false;
210 }
211
212 if (ec)
213 {
214 std::string err = "getPendingList: error while trying to get "
215 "PendingAttributes, error = ";
216 err += ec.message();
217
218 phosphor::logging::log<phosphor::logging::level::ERR>(err.c_str());
219
220 return false;
221 }
222
223 const PendingAttributesType* pendingAttributes =
224 std::get_if<PendingAttributesType>(&pendingAttributesData);
225 if (!pendingAttributes)
226 {
227 phosphor::logging::log<phosphor::logging::level::ERR>(
228 "getPendingList: pendingAttributes is null");
229 return false;
230 }
231
232 for (const auto& [key, attributes] : *pendingAttributes)
233 {
234 const std::string& itemType = std::get<0>(attributes);
235 AttributesType attrType = getAttrType(itemType);
236
237 if (!fillPayloadData(payloadData, std::get<1>(attributes), key,
238 attrType))
239 {
240 return false;
241 }
242 }
243
244 if (payloadData.empty())
245 {
246 phosphor::logging::log<phosphor::logging::level::ERR>(
247 "getPendingList: payloadData is empty");
248 return false;
249 }
250
251 return true;
252}
253bool updatePayloadFile(std::string& payloadFilePath, std::string payloadData)
254{
255 std::ofstream payloadFile(payloadFilePath,
256 std::ios::out | std::ios::binary);
257
258 payloadFile << payloadData;
259
260 if (!payloadFile.good())
261 {
262 return false;
263 }
264
265 return true;
266}
267
268bool computeCheckSum(std::string& payloadFilePath,
269 boost::crc_32_type& calcChecksum)
270{
271 std::ifstream payloadFile(payloadFilePath.c_str(),
272 std::ios::in | std::ios::binary | std::ios::ate);
273
274 if (!payloadFile.good())
275 {
276 phosphor::logging::log<phosphor::logging::level::ERR>(
277 "computeCheckSum: Cannot open Payload1 file");
278 return false;
279 }
280
281 payloadFile.seekg(0, payloadFile.end);
282 int length = payloadFile.tellg();
283 payloadFile.seekg(0, payloadFile.beg);
284
285 if (maxGetPayloadDataSize < length)
286 {
287 phosphor::logging::log<phosphor::logging::level::ERR>(
288 "computeCheckSum: length > maxGetPayloadDataSize");
289 return false;
290 }
291
292 std::unique_ptr<char[]> payloadBuffer(new char[length]);
293
294 payloadFile.read(payloadBuffer.get(), length);
295 uint32_t readCount = payloadFile.gcount();
296
297 calcChecksum.process_bytes(payloadBuffer.get(), readCount);
298
299 return true;
300}
301
302bool updatePayloadInfo(std::string& payloadFilePath)
303{
304 boost::crc_32_type calcChecksum;
305
306 uint8_t payloadType = static_cast<uint8_t>(ipmi::PType::IntelXMLType1);
307 auto& payloadInfo = gNVOOBdata.payloadInfo[payloadType];
308
309 if (!computeCheckSum(payloadFilePath, calcChecksum))
310 {
311 phosphor::logging::log<phosphor::logging::level::ERR>(
312 "updatePayloadInfo: Cannot compute checksum for Payload1 file");
313 return false;
314 }
315
316 payloadInfo.payloadVersion = 0;
317 payloadInfo.payloadflag = 0;
318 payloadInfo.payloadReservationID = rand();
319
320 payloadInfo.payloadType = payloadType;
321
322 payloadInfo.payloadTotalChecksum = calcChecksum.checksum();
323 payloadInfo.payloadCurrentChecksum = payloadInfo.payloadTotalChecksum;
324
325 payloadInfo.payloadStatus = (static_cast<uint8_t>(ipmi::PStatus::Valid));
326
327 struct stat filestat;
328 /* Get entry's information. */
329 if (!stat(payloadFilePath.c_str(), &filestat))
330 {
331 payloadInfo.payloadTimeStamp = filestat.st_mtime;
332 payloadInfo.payloadTotalSize = filestat.st_size;
333 payloadInfo.payloadCurrentSize = filestat.st_size;
334 payloadInfo.actualTotalPayloadWritten = filestat.st_size;
335 }
336 else
337 {
338 phosphor::logging::log<phosphor::logging::level::ERR>(
339 "updatePayloadInfo: Cannot get file status for Payload1 file");
340 return false;
341 }
342
343 if (!flushNVOOBdata())
344 {
345 phosphor::logging::log<phosphor::logging::level::ERR>(
346 "updatePayloadInfo: flushNVOOBdata failed");
347 return false;
348 }
349
350 return true;
351}
352
353bool update(ipmi::Context::ptr ctx)
354{
355 std::string payloadFilePath =
356 "/var/oob/Payload" +
357 std::to_string(static_cast<uint8_t>(ipmi::PType::IntelXMLType1));
358
359 std::string payloadData;
360
361 if (!getPendingList(ctx, payloadData))
362 {
363 phosphor::logging::log<phosphor::logging::level::ERR>(
364 "payload1::update : getPendingList() failed");
365 return false;
366 }
367
368 if (!updatePayloadFile(payloadFilePath, payloadData))
369 {
370 phosphor::logging::log<phosphor::logging::level::ERR>(
371 "payload1::update : updatePayloadFile() failed");
372 return false;
373 }
374
375 if (!updatePayloadInfo(payloadFilePath))
376 {
377 phosphor::logging::log<phosphor::logging::level::ERR>(
378 "payload1::update : updatePayloadInfo() failed");
379 return false;
380 }
381
382 return true;
383}
384} // namespace payload1
385
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800386/** @brief implement to set the BaseBIOSTable property
387 * @returns status
388 */
Arun Lal K Me7725612021-07-15 18:20:58 +0000389static bool sendAllAttributes(std::string service)
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800390{
Arun Lal K Me7725612021-07-15 18:20:58 +0000391 std::shared_ptr<sdbusplus::asio::connection> pSdBusPlus = getSdBus();
392
393 if (pSdBusPlus)
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800394 {
Arun Lal K Me7725612021-07-15 18:20:58 +0000395 try
396 {
397 pSdBusPlus->async_method_call(
398 [](const boost::system::error_code ec) {
399 /* No more need to keep attributes data in memory */
400 attributesData.clear();
401
402 if (ec)
403 {
404 phosphor::logging::log<phosphor::logging::level::ERR>(
405 "sendAllAttributes error: send all attributes - "
406 "failed");
407 return;
408 }
409
410 phosphor::logging::log<phosphor::logging::level::INFO>(
411 "sendAllAttributes: send all attributes - done");
412 },
413 service, biosConfigBaseMgrPath,
414 "org.freedesktop.DBus.Properties", "Set", biosConfigIntf,
415 "BaseBIOSTable",
416 std::variant<bios::BiosBaseTableType>(attributesData));
417
418 return true;
419 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500420 catch (const std::exception& ex)
Arun Lal K Me7725612021-07-15 18:20:58 +0000421 {
422 phosphor::logging::log<phosphor::logging::level::ERR>(ex.what());
423 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800424 }
Arun Lal K Me7725612021-07-15 18:20:58 +0000425
426 return false;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800427}
428
429/** @brief implement to flush the updated data in nv space
430 * @returns status
431 */
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000432static bool flushNVOOBdata()
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800433{
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000434 std::ofstream outFile(biosConfigNVPath, std::ios::binary);
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000435
436 outFile.seekp(std::ios_base::beg);
437 const char* writedata = reinterpret_cast<const char*>(&gNVOOBdata);
438 outFile.write(writedata, sizeof(struct NVOOBdata));
439
440 if (!outFile.good())
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800441 {
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000442 return false;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800443 }
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000444
445 return true;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800446}
447
448/** @brief implement to get the System State
449 * @returns status
450 */
451
452static int getSystemOSState(std::string& OsStatus)
453{
454
455 try
456 {
457 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
458 Value variant =
459 getDbusProperty(*dbus, "xyz.openbmc_project.State.OperatingSystem",
460 "/xyz/openbmc_project/state/os",
461 "xyz.openbmc_project.State.OperatingSystem.Status",
462 "OperatingSystemState");
463 OsStatus = std::get<std::string>(variant);
464 return ipmi::ccSuccess;
465 }
466 catch (const std::exception& e)
467 {
468 return ipmi::ccUnspecifiedError;
469 }
470}
471
472/** @brief implement to get the Rest BIOS property
473 * @returns status
474 */
475static int getResetBIOSSettings(uint8_t& ResetFlag)
476{
477
478 try
479 {
480 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
481 std::string service =
482 getService(*dbus, biosConfigIntf, biosConfigBaseMgrPath);
483 Value variant = getDbusProperty(*dbus, service, biosConfigBaseMgrPath,
484 biosConfigIntf, resetBIOSSettingsProp);
Suryakanth Sekarcc402592021-04-01 15:02:10 +0530485
486 std::string_view ResetStr = std::get<std::string>(variant);
487 if (ResetStr ==
488 "xyz.openbmc_project.BIOSConfig.Manager.ResetFlag.NoAction")
489 {
490 ResetFlag = 0;
491 }
492 else if (ResetStr == "xyz.openbmc_project.BIOSConfig.Manager.ResetFlag."
493 "FactoryDefaults")
494 {
495 ResetFlag = 1;
496 }
497 else if (ResetStr == "xyz.openbmc_project.BIOSConfig.Manager.ResetFlag."
498 "FailSafeDefaults")
499 {
500 ResetFlag = 2;
501 }
502 else
503 {
504 return ipmi::ccUnspecifiedError;
505 }
506
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800507 return ipmi::ccSuccess;
508 }
509 catch (const std::exception& e)
510 {
511 return ipmi::ccUnspecifiedError;
512 }
513}
514
Arun Lal K Me7725612021-07-15 18:20:58 +0000515/** @brief Get attributes data (bios base table) from bios.xml
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800516 */
Arun Lal K Me7725612021-07-15 18:20:58 +0000517static bool generateAttributesData()
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800518{
Arun Lal K Me7725612021-07-15 18:20:58 +0000519 try
520 {
521 bios::Xml biosxml(biosXMLFilePath);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800522
Arun Lal K Me7725612021-07-15 18:20:58 +0000523 if (!biosxml.doDepexCompute())
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800524 {
Arun Lal K Me7725612021-07-15 18:20:58 +0000525 phosphor::logging::log<phosphor::logging::level::ERR>(
526 "'depex' compute failed");
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800527 }
Arun Lal K Me7725612021-07-15 18:20:58 +0000528
529 if (!biosxml.getBaseTable(attributesData))
530 {
531 phosphor::logging::log<phosphor::logging::level::ERR>(
532 "Failed to get bios base table");
533 }
534 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500535 catch (const std::exception& ex)
Arun Lal K Me7725612021-07-15 18:20:58 +0000536 {
537 phosphor::logging::log<phosphor::logging::level::ERR>(ex.what());
538 return false;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800539 }
540
Arun Lal K Me7725612021-07-15 18:20:58 +0000541 return true;
542}
543
544/** @brief Generate attributes data from bios.xml
545 * and send attributes data (bios base table) to dbus using set method.
546 */
547static void generateAndSendAttributesData(std::string service,
548 uint8_t payloadType)
549{
550 if (!generateAttributesData())
551 {
552 phosphor::logging::log<phosphor::logging::level::ERR>(
553 "generateAndSendAttributesData: generateAttributesData - failed");
554 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
555 static_cast<uint8_t>(ipmi::PStatus::Corrupted);
556 return;
557 }
558
559 phosphor::logging::log<phosphor::logging::level::INFO>(
560 "generateAndSendAttributesData : generateAttributesData is done");
561
562 if (!sendAllAttributes(service))
563 {
564 phosphor::logging::log<phosphor::logging::level::ERR>(
565 "generateAndSendAttributesData: sendAllAttributes - failed");
566 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
567 static_cast<uint8_t>(ipmi::PStatus::Corrupted);
568 return;
569 }
570
571 phosphor::logging::log<phosphor::logging::level::INFO>(
572 "generateAndSendAttributesData : sendAllAttributes is done");
573 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
574 static_cast<uint8_t>(ipmi::PStatus::Valid);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800575}
576
577/** @brief implement executing the linux command to uncompress and generate the
578 * xmlfile
579 * @param[in] linux command
580 * @returns status
581 */
582template <typename... ArgTypes>
583static int generateBIOSXMLFile(const char* path, ArgTypes&&... tArgs)
584{
585
586 boost::process::child execProg(path, const_cast<char*>(tArgs)...,
587 boost::process::std_out > biosXMLFilePath);
588 execProg.wait();
589 return execProg.exit_code();
590}
591
592/** @brief implements to clean up the temp/ existing payload file
593 **/
594static void cleanUpPayloadFile(uint8_t& payloadType)
595{
596 // Clear the payload Information
597 std::string FilePath = "/var/oob/temp" + std::to_string(payloadType);
598 unlink(FilePath.c_str());
599 FilePath = "/var/oob/Payload" + std::to_string(payloadType);
600 unlink(FilePath.c_str());
601 if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
602 {
603 unlink("/var/oob/Payload1");
604 gNVOOBdata.payloadInfo[static_cast<uint8_t>(ipmi::PType::IntelXMLType1)]
605 .payloadStatus = static_cast<uint8_t>(ipmi::PStatus::Unknown);
606 }
607}
608
609/** @brief implements to create the oob folders and nv space
610 **/
611static Cc InitNVOOBdata()
612{
613 FILE* fptr;
614 uint16_t size;
615
616 if (!(std::filesystem::exists(biosConfigFolder)))
617 {
618 std::filesystem::create_directory(biosConfigFolder);
619 }
620
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000621 std::ifstream ifs(biosConfigNVPath, std::ios::in | std::ios::binary);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800622
623 if (ifs.good())
624 {
625
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000626 ifs.seekg(std::ios_base::beg);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800627 ifs.read(reinterpret_cast<char*>(&gNVOOBdata),
628 sizeof(struct NVOOBdata));
629 ifs.close();
630 return ipmi::ccSuccess;
631 }
632 return ipmi::ccResponseError;
633}
634
635/** @brief implements check the command interface is
636 ** system interface or not
637 ** true mean System interface and false mean LAN or IPMB
638 **/
639static bool IsSystemInterface(ipmi::Context::ptr ctx)
640{
641 ChannelInfo chInfo;
642 Cc status = false;
643
644 try
645 {
646 getChannelInfo(ctx->channel, chInfo);
647 }
Patrick Williamsbd51e6a2021-10-06 13:09:44 -0500648 catch (const sdbusplus::exception_t& e)
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800649 {
650 return false;
651 }
652 if (chInfo.mediumType !=
653 static_cast<uint8_t>(EChannelMediumType::systemInterface))
654 {
655 return false;
656 }
657 return true;
658}
659
660ipmi::RspType<> ipmiOEMSetBIOSCap(ipmi::Context::ptr ctx,
661 uint8_t BIOSCapabilties, uint8_t reserved1,
662 uint8_t reserved2, uint8_t reserved3)
663{
664 std::string OSState;
665 getSystemOSState(OSState);
666
667 if (OSState != "OperatingState" && IsSystemInterface(ctx))
668 {
669 if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0)
670 {
671 return ipmi::responseInvalidFieldRequest();
672 }
673
674 gNVOOBdata.mBIOSCapabilities.OOBCapability = BIOSCapabilties;
675 gNVOOBdata.mIsBIOSCapInitDone = true;
676
677 flushNVOOBdata();
678 return ipmi::responseSuccess();
679 }
680 else
681 {
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800682 return ipmi::response(ipmiCCNotSupportedInCurrentState);
683 }
684}
685
686ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t>
687 ipmiOEMGetBIOSCap(ipmi::Context::ptr ctx)
688{
689 if (gNVOOBdata.mIsBIOSCapInitDone)
690 {
691 return ipmi::responseSuccess(gNVOOBdata.mBIOSCapabilities.OOBCapability,
692 0, 0, 0);
693 }
694 else
695 {
696 return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
697 }
698}
699
700ipmi::RspType<uint32_t> ipmiOEMSetPayload(ipmi::Context::ptr ctx,
701 uint8_t paramSel, uint8_t payloadType,
702 std::vector<uint8_t> payload)
703{
704 uint8_t biosCapOffsetBit = 2; // BIT:1 0-OOB BIOS config not supported
705 // 1-OOB BIOS config is supported
706
707 if (!(gNVOOBdata.mBIOSCapabilities.OOBCapability & (biosCapOffsetBit)))
708 {
709 return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
710 }
711 // Validate the Payload Type
712 if (payloadType > maxPayloadSupported)
713 {
714 return ipmi::responseInvalidFieldRequest();
715 }
716
717 // We should support this Payload type 0 command only in KCS Interface
718 if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
719 {
720 std::string OSState;
721
722 getSystemOSState(OSState);
723 if (!IsSystemInterface(ctx) || OSState == "OperatingState")
724 {
725 return ipmi::responseCommandNotAvailable();
726 }
727 }
728
729 switch (static_cast<PTState>(paramSel))
730 {
731 case ipmi::PTState::StartTransfer:
732 {
733 PayloadStartTransfer* pPayloadStartTransfer =
734 reinterpret_cast<PayloadStartTransfer*>(payload.data());
735 if (payload.size() < sizeof(PayloadStartTransfer))
736 {
737 phosphor::logging::log<phosphor::logging::level::ERR>(
738 "ipmiOEMSetPayload: BIOS Config Payload size is not "
739 "correct");
740 return ipmi::responseReqDataLenInvalid();
741 }
742 cleanUpPayloadFile(payloadType);
743
744 gNVOOBdata.payloadInfo[payloadType].payloadReservationID = rand();
745 gNVOOBdata.payloadInfo[payloadType].payloadTotalChecksum =
746 pPayloadStartTransfer->payloadTotalChecksum;
747 gNVOOBdata.payloadInfo[payloadType].payloadTotalSize =
748 pPayloadStartTransfer->payloadTotalSize;
749 gNVOOBdata.payloadInfo[payloadType].payloadVersion =
750 pPayloadStartTransfer->payloadVersion;
751 gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten = 0;
752 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
753 static_cast<uint8_t>(ipmi::PStatus::Unknown);
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000754 gNVOOBdata.payloadInfo[payloadType].payloadType = payloadType;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800755
756 return ipmi::responseSuccess(
757 gNVOOBdata.payloadInfo[payloadType].payloadReservationID);
758 }
759 break;
760
761 case ipmi::PTState::InProgress:
762 {
763 PayloadInProgress* pPayloadInProgress =
764 reinterpret_cast<PayloadInProgress*>(payload.data());
765 PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
766
767 if (payload.size() < sizeof(PayloadInProgress))
768 {
769 phosphor::logging::log<phosphor::logging::level::ERR>(
770 "BIOS Config Payload size is not correct");
771 return ipmi::responseReqDataLenInvalid();
772 }
773
774 if (pPayloadInProgress->payloadReservationID !=
775 payloadInfo.payloadReservationID)
776 {
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000777 phosphor::logging::log<phosphor::logging::level::ERR>(
778 "BIOS Config Payload reservation ID is not correct");
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800779 return ipmi::responseInvalidReservationId();
780 }
781 payloadInfo.payloadCurrentSize =
782 pPayloadInProgress->payloadCurrentSize;
783 // Need to verify the current Payload Checksum
784 const uint8_t* data =
785 reinterpret_cast<const uint8_t*>(payload.data());
786 // we have to remove the current size, current offset, current
787 // length,checksum bytes , reservation bytes
788 boost::crc_32_type calcChecksum;
789 calcChecksum.process_bytes(data + 16, payload.size() - 16);
790 if (calcChecksum.checksum() !=
791 pPayloadInProgress->payloadCurrentChecksum)
792 {
793 phosphor::logging::log<phosphor::logging::level::ERR>(
794 "ipmiOEMSetPayload: Payload Checksum Failed");
795 return ipmi::response(ipmiCCPayloadChecksumFailed);
796 }
797 // store the data in temp file
798 std::string FilePath =
799 "/var/oob/temp" + std::to_string(payloadType);
800
801 std::ofstream outFile(FilePath, std::ios::binary | std::ios::app);
802 outFile.seekp(pPayloadInProgress->payloadOffset);
803 // we have to remove the current size, current offset, current
804 // length,checksum bytes , reservation bytes
805
806 const char* writedata =
807 reinterpret_cast<const char*>(payload.data());
808 outFile.write(writedata + 16, payload.size() - 16);
809 outFile.close();
810
811 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
812 static_cast<uint8_t>(ipmi::PStatus::Unknown);
813 gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten +=
814 payloadInfo.payloadCurrentSize;
815 return ipmi::responseSuccess(payloadInfo.payloadCurrentSize);
816 }
817 break;
818 case ipmi::PTState::EndTransfer:
819 {
820 PayloadEndTransfer* pPayloadEndTransfer =
821 reinterpret_cast<PayloadEndTransfer*>(payload.data());
822 PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
823 if (pPayloadEndTransfer->payloadReservationID !=
824 payloadInfo.payloadReservationID)
825 {
826 return ipmi::responseInvalidReservationId();
827 }
828 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
829 static_cast<uint8_t>(ipmi::PStatus::Unknown);
830
831 if (gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten !=
832 gNVOOBdata.payloadInfo[payloadType].payloadTotalSize)
833 {
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800834 return ipmi::response(ipmiCCPayloadPayloadInComplete);
835 }
836 std::string tempFilePath =
837 "/var/oob/temp" + std::to_string(payloadType);
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000838 std::string payloadFilePath =
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800839 "/var/oob/Payload" + std::to_string(payloadType);
840 auto renamestatus =
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000841 std::rename(tempFilePath.c_str(), payloadFilePath.c_str());
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800842 if (renamestatus)
843 {
844 phosphor::logging::log<phosphor::logging::level::ERR>(
845 "ipmiOEMSetPayload: Renaming Payload file - failed");
846 }
847
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800848 if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
849 {
850 // Unzip the Intel format XML file type 0
851 auto response = generateBIOSXMLFile("/usr/bin/lzcat", "-d",
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000852 payloadFilePath.c_str());
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800853 if (response)
854 {
855
856 phosphor::logging::log<phosphor::logging::level::ERR>(
857 "ipmiOEMSetPayload: generateBIOSXMLFile - failed");
858 gNVOOBdata.payloadInfo[payloadType].payloadStatus =
859 static_cast<uint8_t>(ipmi::PStatus::Corrupted);
860 return ipmi::response(ipmiCCPayloadPayloadPacketMissed);
861 }
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000862 phosphor::logging::log<phosphor::logging::level::INFO>(
863 " ipmiOEMSetPayload : Convert XML into native-dbus DONE");
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000864
Arun Lal K Me7725612021-07-15 18:20:58 +0000865 /* So that we don't block the call */
866 auto io = getIoContext();
867 auto dbus = getSdBus();
868 if (io && dbus)
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000869 {
Arun Lal K Me7725612021-07-15 18:20:58 +0000870 std::string service = getService(*dbus, biosConfigIntf,
871 biosConfigBaseMgrPath);
872
873 boost::asio::post(*io, [service, payloadType] {
874 generateAndSendAttributesData(service, payloadType);
875 });
876 }
877 else
878 {
879 phosphor::logging::log<phosphor::logging::level::INFO>(
880 "ipmiOEMSetPayload: Unable to get io context or sdbus");
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000881 return ipmi::responseResponseError();
882 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800883 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800884
885 struct stat filestat;
886
887 /* Get entry's information. */
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000888 if (!stat(payloadFilePath.c_str(), &filestat))
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800889 {
890 gNVOOBdata.payloadInfo[payloadType].payloadTimeStamp =
891 filestat.st_mtime;
892 gNVOOBdata.payloadInfo[payloadType].payloadTotalSize =
893 filestat.st_size;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800894 }
895 else
896 {
897 return ipmi::responseResponseError();
898 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800899 flushNVOOBdata();
900 return ipmi::responseSuccess(
901 gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten);
902 }
903 break;
904 case ipmi::PTState::UserAbort:
905 {
906 PayloadEndTransfer* pPayloadEndTransfer =
907 reinterpret_cast<PayloadEndTransfer*>(payload.data());
908 PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
909 if (pPayloadEndTransfer->payloadReservationID !=
910 payloadInfo.payloadReservationID)
911 {
912 return ipmi::responseInvalidReservationId();
913 }
914 gNVOOBdata.payloadInfo[payloadType].payloadReservationID = 0;
915 gNVOOBdata.payloadInfo[payloadType].payloadType = 0;
916 gNVOOBdata.payloadInfo[payloadType].payloadTotalSize = 0;
917 // Delete the temp file
918 std::string tempFilePath =
919 "/var/oob/temp" + std::to_string(payloadType);
920 unlink(tempFilePath.c_str());
921 flushNVOOBdata();
922 return ipmi::responseSuccess();
923 }
924 break;
925 default:
926 return ipmi::responseInvalidFieldRequest();
927 }
928 return ipmi::responseResponseError();
929}
930
931ipmi::RspType<message::Payload>
932 ipmiOEMGetPayload(ipmi::Context::ptr ctx, uint8_t paramSel,
933 uint8_t payloadType, ipmi::message::Payload& payload)
934{
935 // 1-OOB BIOS config is supported
936 message::Payload retValue;
937
938 if (!(gNVOOBdata.mBIOSCapabilities.OOBCapability & (biosCapOffsetBit)))
939 {
940 return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
941 }
942 // Validate the Payload Type
943 if (payloadType > maxPayloadSupported)
944 {
945 return ipmi::responseInvalidFieldRequest();
946 }
947
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000948 if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType1))
949 {
950 if (!payload1::update(ctx))
951 {
952 phosphor::logging::log<phosphor::logging::level::ERR>(
953 "ipmiOEMGetPayload: unable to update NVOOBdata for payloadType "
954 "= IntelXMLType1");
955 return ipmi::response(ipmi::ccUnspecifiedError);
956 }
957 }
958
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800959 struct PayloadInfo res = gNVOOBdata.payloadInfo[payloadType];
960
961 switch (static_cast<GetPayloadParameter>(paramSel))
962 {
963 case ipmi::GetPayloadParameter::GetPayloadInfo:
964 {
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000965 std::string payloadFilePath =
966 "/var/oob/Payload" + std::to_string(payloadType);
967
968 std::ifstream ifs(payloadFilePath,
969 std::ios::in | std::ios::binary | std::ios::ate);
970
971 if (!ifs.good())
972 {
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000973 phosphor::logging::log<phosphor::logging::level::ERR>(
974 "ipmiOEMGetPayload: Payload File Error");
975 // File does not exist code here
976 return ipmi::response(ipmi::ccUnspecifiedError);
977 }
Arun Lal K Mb0caca02021-09-05 22:09:33 +0000978
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000979 ifs.close();
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800980 retValue.pack(res.payloadVersion);
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +0000981 retValue.pack(payloadType);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +0800982 retValue.pack(res.payloadTotalSize);
983 retValue.pack(res.payloadTotalChecksum);
984 retValue.pack(res.payloadflag);
985 retValue.pack(res.payloadStatus);
986 retValue.pack(res.payloadTimeStamp);
987
988 return ipmi::responseSuccess(std::move(retValue));
989 }
990
991 break;
992 case ipmi::GetPayloadParameter::GetPayloadData:
993 {
994 if (res.payloadStatus ==
995 (static_cast<uint8_t>(ipmi::PStatus::Valid)))
996 {
997 std::vector<uint32_t> reqData;
998 if (payload.unpack(reqData) || !payload.fullyUnpacked())
999 {
1000 return ipmi::responseReqDataLenInvalid();
1001 }
1002 uint32_t offset = reqData.at(0);
1003 uint32_t length = reqData.at(1);
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +00001004 std::string payloadFilePath =
1005 "/var/oob/Payload" + std::to_string(payloadType);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001006
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +00001007 std::ifstream ifs(payloadFilePath, std::ios::in |
1008 std::ios::binary |
1009 std::ios::ate);
1010
1011 if (!ifs.good())
1012 {
Suryakanth Sekar5dd161f2021-06-16 13:02:25 +00001013 phosphor::logging::log<phosphor::logging::level::ERR>(
1014 "ipmiOEMGetPayload: Payload File Error");
1015 // File does not exist code here
1016 return ipmi::response(ipmi::ccUnspecifiedError);
1017 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001018 std::ifstream::pos_type fileSize = ifs.tellg();
1019 // Total file data within given offset
1020 if (fileSize < static_cast<uint64_t>(offset))
1021 {
1022 ifs.close();
1023 return ipmi::responseInvalidFieldRequest();
1024 }
1025
1026 ifs.seekg(offset, std::ios::beg);
1027 std::array<uint8_t, maxGetPayloadDataSize> Buffer;
1028 ifs.read(reinterpret_cast<char*>(Buffer.data()), length);
1029 uint32_t readCount = ifs.gcount();
1030 ifs.close();
1031
1032 boost::crc_32_type calcChecksum;
1033 calcChecksum.process_bytes(
1034 reinterpret_cast<char*>(Buffer.data()), readCount);
1035 uint32_t chkSum = calcChecksum.checksum();
1036 retValue.pack(payloadType);
1037 retValue.pack(readCount);
1038 retValue.pack(chkSum);
1039
1040 for (int i = 0; i < readCount; i++)
1041 {
1042 retValue.pack(Buffer.at(i));
1043 }
Arun Lal K Mb0caca02021-09-05 22:09:33 +00001044
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001045 return ipmi::responseSuccess(std::move(retValue));
1046 }
1047 else
1048 {
1049 return ipmi::responseResponseError();
1050 }
1051 }
1052 break;
1053 case ipmi::GetPayloadParameter::GetPayloadStatus:
1054 {
1055 retValue.pack(gNVOOBdata.payloadInfo[payloadType].payloadStatus);
1056 return ipmi::responseSuccess(std::move(retValue));
1057 }
1058 break;
1059 default:
1060 return ipmi::responseInvalidFieldRequest();
1061 }
1062 return ipmi::responseInvalidFieldRequest();
1063}
1064
1065ipmi::RspType<> ipmiOEMSetBIOSHashInfo(
1066 ipmi::Context::ptr ctx, std::array<uint8_t, maxSeedSize>& pwdSeed,
Ayushi Smriti32381872021-06-23 11:05:48 +05301067 uint8_t algoInfo, std::array<uint8_t, maxHashSize>& adminPwdHash)
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001068{
1069
1070 std::string OSState;
1071
1072 // We should support this command only in KCS Interface
1073 if (!IsSystemInterface(ctx))
1074 {
1075 return ipmi::responseCommandNotAvailable();
1076 }
1077 getSystemOSState(OSState);
1078 // We should not support this command after System Booted - After Exit Boot
1079 // service called
1080
Ayushi Smriti32381872021-06-23 11:05:48 +05301081 if (OSState == "OperatingState")
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001082 {
Ayushi Smriti32381872021-06-23 11:05:48 +05301083 return ipmi::response(ipmiCCNotSupportedInCurrentState);
1084 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001085
Ayushi Smriti32381872021-06-23 11:05:48 +05301086 nlohmann::json json;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001087
Ayushi Smriti32381872021-06-23 11:05:48 +05301088 if ((algoInfo & 0xF) == algoSHA384)
1089 {
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001090 json["HashAlgo"] = "SHA384";
Ayushi Smriti32381872021-06-23 11:05:48 +05301091 }
1092 else if ((algoInfo & 0xF) == algoSHA256)
1093 {
1094 json["HashAlgo"] = "SHA256";
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001095 }
1096 else
1097 {
Ayushi Smriti32381872021-06-23 11:05:48 +05301098 return ipmi::responseInvalidFieldRequest();
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001099 }
Ayushi Smriti32381872021-06-23 11:05:48 +05301100
1101 json["Seed"] = pwdSeed;
1102 json["IsAdminPwdChanged"] = false;
1103 json["AdminPwdHash"] = adminPwdHash;
1104 json["IsUserPwdChanged"] = false;
1105
1106 std::array<uint8_t, maxHashSize> userPwdHash;
1107 userPwdHash.fill({}); // initializing with 0 as user password hash field
1108 // is not used presently
1109 json["UserPwdHash"] = userPwdHash;
1110 json["StatusFlag"] = algoInfo;
1111
1112 std::string hashFilePath = "/var/lib/bios-settings-manager/seedData";
1113 std::ofstream ofs(hashFilePath, std::ios::out);
1114 const auto& writeData = json.dump();
1115 ofs << writeData;
1116 ofs.close();
1117 return ipmi::responseSuccess();
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001118}
1119
Ayushi Smriti32381872021-06-23 11:05:48 +05301120ipmi::RspType<std::array<uint8_t, maxSeedSize>, uint8_t,
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001121 std::array<uint8_t, maxHashSize>>
1122 ipmiOEMGetBIOSHash(ipmi::Context::ptr ctx)
1123{
1124
1125 std::string OSState;
1126 nlohmann::json data = nullptr;
1127
1128 // We should support this command only in KCS Interface
1129 if (!IsSystemInterface(ctx))
1130 {
1131 return ipmi::responseCommandNotAvailable();
1132 }
1133
1134 getSystemOSState(OSState);
1135 // We should not support this command after System Booted - After Exit Boot
1136 // service called
1137
1138 if (OSState != "OperatingState")
1139 {
Suryakanth Sekarcc402592021-04-01 15:02:10 +05301140 std::string HashFilePath = "/var/lib/bios-settings-manager/seedData";
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001141
1142 std::ifstream devIdFile(HashFilePath);
1143 if (devIdFile.is_open())
1144 {
1145
1146 try
1147 {
1148 data = nlohmann::json::parse(devIdFile, nullptr, false);
1149 }
1150 catch (const nlohmann::json::parse_error& e)
1151 {
1152 return ipmi::responseResponseError();
1153 }
1154
1155 if (data.is_discarded())
1156 {
1157 return ipmi::responseResponseError();
1158 }
1159
1160 std::array<uint8_t, maxHashSize> newAdminHash;
Ayushi Smriti32381872021-06-23 11:05:48 +05301161 std::array<uint8_t, maxSeedSize> seed;
1162
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001163 uint8_t flag = 0;
1164 uint8_t adminPwdChangedFlag = 0;
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001165 if (!data.is_discarded())
1166 {
1167
1168 adminPwdChangedFlag = data["IsAdminPwdChanged"];
1169 newAdminHash = data["AdminPwdHash"];
Ayushi Smriti32381872021-06-23 11:05:48 +05301170 seed = data["Seed"];
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001171 }
1172
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001173 auto status = getResetBIOSSettings(flag);
1174 if (status)
1175 {
1176 return ipmi::responseResponseError();
1177 }
1178 if (adminPwdChangedFlag)
1179 {
1180 flag |= adminPasswordChanged;
1181 }
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001182
1183 std::copy(std::begin(newAdminHash), std::end(newAdminHash),
1184 std::begin(newAdminHash));
Ayushi Smriti32381872021-06-23 11:05:48 +05301185
1186 return ipmi::responseSuccess(seed, flag, newAdminHash);
Kuiying Wang6d6dc7a2020-04-02 10:15:19 +08001187 }
1188 else
1189 {
1190 return ipmi::responseResponseError();
1191 }
1192 }
1193 else
1194 {
1195
1196 return ipmi::response(ipmiCCNotSupportedInCurrentState);
1197 }
1198}
1199
1200static void registerBIOSConfigFunctions(void)
1201{
1202 phosphor::logging::log<phosphor::logging::level::INFO>(
1203 "BIOSConfig module initialization");
1204 InitNVOOBdata();
1205
1206 registerHandler(prioOemBase, intel::netFnGeneral,
1207 intel::general::cmdSetBIOSCap, Privilege::Admin,
1208 ipmiOEMSetBIOSCap);
1209
1210 registerHandler(prioOemBase, intel::netFnGeneral,
1211 intel::general::cmdGetBIOSCap, Privilege::User,
1212 ipmiOEMGetBIOSCap);
1213 registerHandler(prioOemBase, intel::netFnGeneral,
1214 intel::general::cmdSetBIOSPwdHashInfo, Privilege::Admin,
1215 ipmiOEMSetBIOSHashInfo);
1216
1217 registerHandler(prioOemBase, intel::netFnGeneral,
1218 intel::general::cmdGetBIOSPwdHash, Privilege::User,
1219 ipmiOEMGetBIOSHash);
1220
1221 registerHandler(prioOemBase, intel::netFnGeneral,
1222 intel::general::cmdGetPayload, Privilege::User,
1223 ipmiOEMGetPayload);
1224 registerHandler(prioOemBase, intel::netFnGeneral,
1225 intel::general::cmdSetPayload, Privilege::Admin,
1226 ipmiOEMSetPayload);
1227
1228 return;
1229}
1230
1231} // namespace ipmi