blob: 2d4e1a98ece93e332814a016ecdb713c81b05be8 [file] [log] [blame]
Vernon Maueryce14e4d2019-06-25 11:38:20 -07001/*
2// Copyright (c) 2019 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*/
Jayaprakash Mutyala1e912992024-10-24 12:52:35 +000016#include "xyz/openbmc_project/Common/error.hpp"
17
AppaRao Pulie99e7ed2020-01-17 12:27:10 +053018#include <byteswap.h>
Vernon Maueryce14e4d2019-06-25 11:38:20 -070019
Chen Yugang7a04f3a2019-10-08 11:12:35 +080020#include <appcommands.hpp>
Vernon Maueryce14e4d2019-06-25 11:38:20 -070021#include <ipmid/api.hpp>
22#include <ipmid/utils.hpp>
23#include <nlohmann/json.hpp>
Jayaprakash Mutyala1e912992024-10-24 12:52:35 +000024#include <phosphor-logging/elog-errors.hpp>
25#include <phosphor-logging/lg2.hpp>
Vernon Maueryce14e4d2019-06-25 11:38:20 -070026#include <phosphor-logging/log.hpp>
Jason M. Bills0748c692022-09-08 15:34:08 -070027#include <types.hpp>
James Feistfcd2d3a2020-05-28 10:38:15 -070028
29#include <fstream>
Vernon Maueryce14e4d2019-06-25 11:38:20 -070030#include <regex>
Vernon Maueryce14e4d2019-06-25 11:38:20 -070031
Jayaprakash Mutyala1e912992024-10-24 12:52:35 +000032using namespace phosphor::logging;
33using namespace sdbusplus::error::xyz::openbmc_project::common;
34
Vernon Maueryce14e4d2019-06-25 11:38:20 -070035namespace ipmi
36{
37
38static void registerAPPFunctions() __attribute__((constructor));
39
AppaRao Pulie99e7ed2020-01-17 12:27:10 +053040static constexpr const char* bmcStateIntf = "xyz.openbmc_project.State.BMC";
41static constexpr const char* softwareVerIntf =
42 "xyz.openbmc_project.Software.Version";
43static constexpr const char* softwareActivationIntf =
44 "xyz.openbmc_project.Software.Activation";
45static constexpr const char* associationIntf =
46 "xyz.openbmc_project.Association";
47static constexpr const char* softwareFunctionalPath =
48 "/xyz/openbmc_project/software/functional";
Vernon Maueryce14e4d2019-06-25 11:38:20 -070049
AppaRao Puli6c6cec42020-02-26 11:56:47 +053050static constexpr const char* currentBmcStateProp = "CurrentBMCState";
51static constexpr const char* bmcStateReadyStr =
52 "xyz.openbmc_project.State.BMC.BMCState.Ready";
Vernon Maueryce14e4d2019-06-25 11:38:20 -070053
Patrick Williamsf944d2e2022-07-22 19:26:52 -050054static std::unique_ptr<sdbusplus::bus::match_t> bmcStateChangedSignal;
AppaRao Puli6c6cec42020-02-26 11:56:47 +053055static uint8_t bmcDeviceBusy = true;
56
57int initBMCDeviceState(ipmi::Context::ptr ctx)
Vernon Maueryce14e4d2019-06-25 11:38:20 -070058{
AppaRao Puli6c6cec42020-02-26 11:56:47 +053059 DbusObjectInfo objInfo;
Patrick Williams1bcced02024-08-16 15:20:24 -040060 boost::system::error_code ec =
61 ipmi::getDbusObject(ctx, bmcStateIntf, "/", "bmc0", objInfo);
AppaRao Puli6c6cec42020-02-26 11:56:47 +053062 if (ec)
Vernon Maueryce14e4d2019-06-25 11:38:20 -070063 {
AppaRao Puli6c6cec42020-02-26 11:56:47 +053064 phosphor::logging::log<phosphor::logging::level::ERR>(
65 "initBMCDeviceState: Failed to perform GetSubTree action",
66 phosphor::logging::entry("ERROR=%s", ec.message().c_str()),
67 phosphor::logging::entry("INTERFACE=%s", bmcStateIntf));
68 return -1;
Vernon Maueryce14e4d2019-06-25 11:38:20 -070069 }
AppaRao Puli6c6cec42020-02-26 11:56:47 +053070
AppaRao Puli6c6cec42020-02-26 11:56:47 +053071 // BMC state may change runtime while doing firmware udpate.
72 // Register for property change signal to update state.
Patrick Williamsf944d2e2022-07-22 19:26:52 -050073 bmcStateChangedSignal = std::make_unique<sdbusplus::bus::match_t>(
AppaRao Puli6c6cec42020-02-26 11:56:47 +053074 *(ctx->bus),
75 sdbusplus::bus::match::rules::propertiesChanged(objInfo.first,
76 bmcStateIntf),
Patrick Williamsf944d2e2022-07-22 19:26:52 -050077 [](sdbusplus::message_t& msg) {
Patrick Williams1bcced02024-08-16 15:20:24 -040078 std::map<std::string, ipmi::DbusVariant> props;
79 std::vector<std::string> inVal;
80 std::string iface;
81 try
AppaRao Puli6c6cec42020-02-26 11:56:47 +053082 {
Patrick Williams1bcced02024-08-16 15:20:24 -040083 msg.read(iface, props, inVal);
AppaRao Puli6c6cec42020-02-26 11:56:47 +053084 }
Patrick Williams1bcced02024-08-16 15:20:24 -040085 catch (const std::exception& e)
86 {
87 phosphor::logging::log<phosphor::logging::level::ERR>(
88 "Exception caught in Get CurrentBMCState");
89 return;
90 }
91
92 auto it = props.find(currentBmcStateProp);
93 if (it != props.end())
94 {
95 std::string* state = std::get_if<std::string>(&it->second);
96 if (state)
97 {
98 bmcDeviceBusy = (*state != bmcStateReadyStr);
99 phosphor::logging::log<phosphor::logging::level::INFO>(
100 "BMC device state updated");
101 }
102 }
103 });
AppaRao Puli6c6cec42020-02-26 11:56:47 +0530104
Johnathan Mantey08698b12024-11-07 13:06:20 -0800105 std::string bmcState;
106 ec = ipmi::getDbusProperty(ctx, objInfo.second, objInfo.first, bmcStateIntf,
107 currentBmcStateProp, bmcState);
108 if (ec)
109 {
110 phosphor::logging::log<phosphor::logging::level::ERR>(
111 "initBMCDeviceState: Failed to get CurrentBMCState property",
112 phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
113 return -1;
114 }
115
116 bmcDeviceBusy = (bmcState != bmcStateReadyStr);
117
118 phosphor::logging::log<phosphor::logging::level::INFO>(
119 "BMC device state updated");
120
AppaRao Puli6c6cec42020-02-26 11:56:47 +0530121 return 0;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700122}
Jia, chunhui82d178c2019-06-27 16:48:14 +0800123
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700124/**
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530125 * @brief Returns the functional firmware version information.
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700126 *
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530127 * It reads the active firmware versions by checking functional
128 * endpoints association and matching the input version purpose string.
129 * ctx[in] - ipmi context.
130 * reqVersionPurpose[in] - Version purpose which need to be read.
131 * version[out] - Output Version string.
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700132 *
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530133 * @return Returns '0' on success and '-1' on failure.
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700134 *
135 */
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530136int getActiveSoftwareVersionInfo(ipmi::Context::ptr ctx,
137 const std::string& reqVersionPurpose,
138 std::string& version)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700139{
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530140 std::vector<std::string> activeEndPoints;
141 boost::system::error_code ec = ipmi::getDbusProperty(
142 ctx, ipmi::MAPPER_BUS_NAME, softwareFunctionalPath, associationIntf,
143 "endpoints", activeEndPoints);
144 if (ec)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700145 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530146 phosphor::logging::log<phosphor::logging::level::ERR>(
147 "Failed to get Active firmware version endpoints.");
148 return -1;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700149 }
150
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530151 for (auto& activeEndPoint : activeEndPoints)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700152 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530153 std::string serviceName;
154 ec = ipmi::getService(ctx, softwareActivationIntf, activeEndPoint,
155 serviceName);
156 if (ec)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700157 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530158 phosphor::logging::log<phosphor::logging::level::ERR>(
159 "Failed to perform getService.",
160 phosphor::logging::entry("OBJPATH=%s", activeEndPoint.c_str()));
161 continue;
162 }
163
164 PropertyMap propMap;
165 ec = ipmi::getAllDbusProperties(ctx, serviceName, activeEndPoint,
166 softwareVerIntf, propMap);
167 if (ec)
168 {
169 phosphor::logging::log<phosphor::logging::level::ERR>(
170 "Failed to perform GetAll on Version interface.",
171 phosphor::logging::entry("SERVICE=%s", serviceName.c_str()),
172 phosphor::logging::entry("PATH=%s", activeEndPoint.c_str()));
173 continue;
174 }
175
176 std::string* purposeProp =
177 std::get_if<std::string>(&propMap["Purpose"]);
178 std::string* versionProp =
179 std::get_if<std::string>(&propMap["Version"]);
180 if (!purposeProp || !versionProp)
181 {
182 phosphor::logging::log<phosphor::logging::level::ERR>(
183 "Failed to get version or purpose property");
184 continue;
185 }
186
187 // Check for requested version information and return if found.
188 if (*purposeProp == reqVersionPurpose)
189 {
190 version = *versionProp;
191 return 0;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700192 }
193 }
194
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530195 phosphor::logging::log<phosphor::logging::level::INFO>(
196 "Failed to find version information.",
197 phosphor::logging::entry("PURPOSE=%s", reqVersionPurpose.c_str()));
198 return -1;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700199}
200
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700201// Support both 2 solutions:
202// 1.Current solution 2.7.0-dev-533-g14dc00e79-5e7d997
203// openbmcTag 2.7.0-dev
204// BuildNo 533
Jia, chunhui82d178c2019-06-27 16:48:14 +0800205// openbmcHash 14dc00e79
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700206// MetaHasg 5e7d997
207//
Jason M. Bills23ad5f12023-09-14 15:21:58 -0700208// 2.New solution wht-0.2-3-gab3500-38384ac or wht-2000.2.3-gab3500-38384ac
Jia, chunhui82d178c2019-06-27 16:48:14 +0800209// IdStr wht
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700210// Major 0
Jia, chunhui82d178c2019-06-27 16:48:14 +0800211// Minor 2
212// buildNo 3
213// MetaHash ab3500
214// openbmcHash 38384ac
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700215std::optional<MetaRevision> convertIntelVersion(std::string& s)
216{
217 std::smatch results;
218 MetaRevision rev;
Jia, chunhui82d178c2019-06-27 16:48:14 +0800219 std::regex pattern1("(\\d+?).(\\d+?).\\d+?-\\w*?-(\\d+?)-g(\\w+?)-(\\w+?)");
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700220 constexpr size_t matchedPhosphor = 6;
221 if (std::regex_match(s, results, pattern1))
222 {
223 if (results.size() == matchedPhosphor)
224 {
225 rev.platform = "whtref";
226 rev.major = static_cast<uint8_t>(std::stoi(results[1]));
227 rev.minor = static_cast<uint8_t>(std::stoi(results[2]));
228 rev.buildNo = static_cast<uint32_t>(std::stoi(results[3]));
229 rev.openbmcHash = results[4];
230 rev.metaHash = results[5];
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700231 std::string versionString =
232 rev.platform + ":" + std::to_string(rev.major) + ":" +
233 std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
Jia, chunhui82d178c2019-06-27 16:48:14 +0800234 ":" + rev.openbmcHash + ":" + rev.metaHash;
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530235 phosphor::logging::log<phosphor::logging::level::INFO>(
Jia, chunhui82d178c2019-06-27 16:48:14 +0800236 "Get BMC version",
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530237 phosphor::logging::entry("VERSION=%s", versionString.c_str()));
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700238 return rev;
239 }
240 }
Jia, chunhui82d178c2019-06-27 16:48:14 +0800241 constexpr size_t matchedIntel = 7;
Jason M. Bills23ad5f12023-09-14 15:21:58 -0700242 std::regex pattern2("(\\w+?)-(\\d+?).(\\d+?)[-.](\\d+?)-g(\\w+?)-(\\w+?)");
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700243 if (std::regex_match(s, results, pattern2))
244 {
245 if (results.size() == matchedIntel)
246 {
247 rev.platform = results[1];
Jason M. Bills23ad5f12023-09-14 15:21:58 -0700248 std::string majorVer = results[2].str();
249 // Take only the last two digits of the major version
250 rev.major = static_cast<uint8_t>(
251 std::stoi(majorVer.substr(majorVer.size() - 2)));
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700252 rev.minor = static_cast<uint8_t>(std::stoi(results[3]));
253 rev.buildNo = static_cast<uint32_t>(std::stoi(results[4]));
Jia, chunhui82d178c2019-06-27 16:48:14 +0800254 rev.openbmcHash = results[6];
255 rev.metaHash = results[5];
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700256 std::string versionString =
257 rev.platform + ":" + std::to_string(rev.major) + ":" +
258 std::to_string(rev.minor) + ":" + std::to_string(rev.buildNo) +
Jia, chunhui82d178c2019-06-27 16:48:14 +0800259 ":" + rev.openbmcHash + ":" + rev.metaHash;
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530260 phosphor::logging::log<phosphor::logging::level::INFO>(
Jia, chunhui82d178c2019-06-27 16:48:14 +0800261 "Get BMC version",
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530262 phosphor::logging::entry("VERSION=%s", versionString.c_str()));
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700263 return rev;
264 }
265 }
266
267 return std::nullopt;
268}
Chen Yugang7a04f3a2019-10-08 11:12:35 +0800269
Jayaprakash Mutyala1e912992024-10-24 12:52:35 +0000270static constexpr size_t uuidLength = 16;
271static std::array<uint8_t, uuidLength>
272 rfc4122ToIpmiConvesrion(std::string rfc4122)
273{
274 using Argument = xyz::openbmc_project::common::InvalidArgument;
275 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
276 // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
277 // order
278 // Ex: 0x2332fc2c40e66298e511f2782395a361
279 constexpr size_t uuidHexLength = (2 * uuidLength);
280 constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
281 std::array<uint8_t, uuidLength> uuid;
282 if (rfc4122.size() == uuidRfc4122Length)
283 {
284 rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
285 rfc4122.end());
286 }
287 if (rfc4122.size() != uuidHexLength)
288 {
289 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
290 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
291 }
292 for (size_t ind = 0; ind < uuidHexLength; ind += 2)
293 {
294 char v[3];
295 v[0] = rfc4122[ind];
296 v[1] = rfc4122[ind + 1];
297 v[2] = 0;
298 size_t err;
299 long b;
300 try
301 {
302 b = std::stoul(v, &err, 16);
303 }
304 catch (const std::exception& e)
305 {
306 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
307 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
308 }
309 // check that exactly two ascii bytes were converted
310 if (err != 2)
311 {
312 elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
313 Argument::ARGUMENT_VALUE(rfc4122.c_str()));
314 }
315 uuid[uuidLength - (ind / 2) - 1] = static_cast<uint8_t>(b);
316 }
317 return uuid;
318}
319
320ipmi::RspType<std::array<uint8_t, 16>>
321 ipmiAppGetSystemGuid(ipmi::Context::ptr& ctx)
322{
323 static constexpr auto uuidInterface = "xyz.openbmc_project.Common.UUID";
324 static constexpr auto uuidProperty = "UUID";
325 // Get the Inventory object implementing BMC interface
326 ipmi::DbusObjectInfo objectInfo{};
327 boost::system::error_code ec =
328 ipmi::getDbusObject(ctx, uuidInterface, objectInfo);
329
330 if (ec.value())
331 {
332 lg2::error("Failed to locate System UUID object, "
333 "interface: {INTERFACE}, error: {ERROR}",
334 "INTERFACE", uuidInterface, "ERROR", ec.message());
335 return ipmi::responseUnspecifiedError();
336 }
337
338 // Read UUID property value from bmcObject
339 // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
340 std::string rfc4122Uuid{};
341 ec = ipmi::getDbusProperty(ctx, objectInfo.second, objectInfo.first,
342 uuidInterface, uuidProperty, rfc4122Uuid);
343
344 if (ec.value())
345 {
346 lg2::error("Failed to read System UUID property, "
347 "interface: {INTERFACE}, property: {PROPERTY}, "
348 "error: {ERROR}",
349 "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
350 "ERROR", ec.message());
351 return ipmi::responseUnspecifiedError();
352 }
353 std::array<uint8_t, 16> uuid;
354 try
355 {
356 // convert to IPMI format
357 uuid = rfc4122ToIpmiConvesrion(rfc4122Uuid);
358 }
359 catch (const InvalidArgument& e)
360 {
361 lg2::error("Failed in parsing BMC UUID property, "
362 "interface: {INTERFACE}, property: {PROPERTY}, "
363 "value: {VALUE}, error: {ERROR}",
364 "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
365 "VALUE", rfc4122Uuid, "ERROR", e);
366 return ipmi::responseUnspecifiedError();
367 }
368 return ipmi::responseSuccess(uuid);
369}
370
Vernon Mauery98bbf692019-09-16 11:14:59 -0700371RspType<uint8_t, // Device ID
372 uint8_t, // Device Revision
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530373 uint7_t, // Firmware Revision Major
374 bool, // Device available(0=NormalMode,1=DeviceFirmware)
Vernon Mauery98bbf692019-09-16 11:14:59 -0700375 uint8_t, // Firmware Revision minor
376 uint8_t, // IPMI version
377 uint8_t, // Additional device support
378 uint24_t, // MFG ID
379 uint16_t, // Product ID
380 uint32_t // AUX info
381 >
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530382 ipmiAppGetDeviceId(ipmi::Context::ptr ctx)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700383{
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700384 static struct
385 {
386 uint8_t id;
387 uint8_t revision;
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530388 uint7_t fwMajor;
389 bool devBusy;
390 uint8_t fwMinor;
Johnathan Mantey3c8af652019-12-19 11:29:15 -0800391 uint8_t ipmiVer = 2;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700392 uint8_t addnDevSupport;
393 uint24_t manufId;
394 uint16_t prodId;
395 uint32_t aux;
396 } devId;
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530397 static bool fwVerInitialized = false;
398 static bool devIdInitialized = false;
AppaRao Puli6c6cec42020-02-26 11:56:47 +0530399 static bool bmcStateInitialized = false;
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700400 const char* filename = "/usr/share/ipmi-providers/dev_id.json";
Johnathan Mantey3c8af652019-12-19 11:29:15 -0800401 const char* prodIdFilename = "/var/cache/private/prodID";
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530402 if (!fwVerInitialized)
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700403 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530404 std::string versionString;
405 if (!getActiveSoftwareVersionInfo(ctx, versionPurposeBMC,
406 versionString))
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700407 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530408 std::optional<MetaRevision> rev =
409 convertIntelVersion(versionString);
410 if (rev.has_value())
Jia, chunhui82d178c2019-06-27 16:48:14 +0800411 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530412 MetaRevision revision = rev.value();
413 devId.fwMajor = static_cast<uint7_t>(revision.major);
414
415 revision.minor = (revision.minor > 99 ? 99 : revision.minor);
Patrick Williamsb37abfb2023-05-10 07:50:33 -0500416 devId.fwMinor = revision.minor % 10 +
417 (revision.minor / 10) * 16;
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530418 try
419 {
420 uint32_t hash = std::stoul(revision.metaHash, 0, 16);
421 hash = bswap_32(hash);
422 devId.aux = (revision.buildNo & 0xFF) + (hash & 0xFFFFFF00);
423 fwVerInitialized = true;
424 }
425 catch (const std::exception& e)
426 {
427 phosphor::logging::log<phosphor::logging::level::ERR>(
428 "Failed to convert git hash",
429 phosphor::logging::entry("ERROR=%s", e.what()));
430 }
Jia, chunhui82d178c2019-06-27 16:48:14 +0800431 }
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700432 }
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530433 }
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700434
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530435 if (!devIdInitialized)
436 {
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700437 std::ifstream devIdFile(filename);
438 if (devIdFile.is_open())
439 {
440 auto data = nlohmann::json::parse(devIdFile, nullptr, false);
441 if (!data.is_discarded())
442 {
443 devId.id = data.value("id", 0);
444 devId.revision = data.value("revision", 0);
445 devId.addnDevSupport = data.value("addn_dev_support", 0);
446 devId.manufId = data.value("manuf_id", 0);
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700447 }
448 else
449 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530450 phosphor::logging::log<phosphor::logging::level::ERR>(
451 "Device ID JSON parser failure");
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700452 return ipmi::responseUnspecifiedError();
453 }
454 }
455 else
456 {
AppaRao Pulie99e7ed2020-01-17 12:27:10 +0530457 phosphor::logging::log<phosphor::logging::level::ERR>(
458 "Device ID file not found");
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700459 return ipmi::responseUnspecifiedError();
460 }
Johnathan Mantey3c8af652019-12-19 11:29:15 -0800461
462 // Determine the Product ID. Using the DBus system is painfully slow at
463 // boot time. Avoid using DBus to get the Product ID. The Product ID is
464 // stored in a non-volatile file now. The /usr/bin/checkFru.sh script,
465 // run during bootup, will populate the productIdFile.
466 std::fstream prodIdFile(prodIdFilename);
467 if (prodIdFile.is_open())
468 {
469 std::string id = "0x00";
470 char* end;
471 prodIdFile.getline(&id[0], id.size() + 1);
472 devId.prodId = std::strtol(&id[0], &end, 0);
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530473 devIdInitialized = true;
Johnathan Mantey3c8af652019-12-19 11:29:15 -0800474 }
475 else
476 {
477 // For any exception send out platform id as 0,
478 // and make sure to re-query the device id.
AppaRao Pulicb6386b2020-01-16 14:53:30 +0530479 devIdInitialized = false;
Johnathan Mantey3c8af652019-12-19 11:29:15 -0800480 devId.prodId = 0;
481 }
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700482 }
483
AppaRao Puli6c6cec42020-02-26 11:56:47 +0530484 if (!bmcStateInitialized)
485 {
486 if (!initBMCDeviceState(ctx))
487 {
488 bmcStateInitialized = true;
489 }
490 }
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700491
Patrick Williams1bcced02024-08-16 15:20:24 -0400492 return ipmi::responseSuccess(
493 devId.id, devId.revision, devId.fwMajor, bmcDeviceBusy, devId.fwMinor,
494 devId.ipmiVer, devId.addnDevSupport, devId.manufId, devId.prodId,
495 devId.aux);
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700496}
497
498static void registerAPPFunctions(void)
499{
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700500 // <Get Device ID>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700501 registerHandler(prioOemBase, netFnApp, app::cmdGetDeviceId, Privilege::User,
502 ipmiAppGetDeviceId);
Jayaprakash Mutyala1e912992024-10-24 12:52:35 +0000503 // <Get System GUID>
504 registerHandler(prioOemBase, netFnApp, app::cmdGetSystemGuid,
505 Privilege::User, ipmiAppGetSystemGuid);
Vernon Maueryce14e4d2019-06-25 11:38:20 -0700506}
507
508} // namespace ipmi