xref: /openbmc/phosphor-power/tools/power-utils/version.cpp (revision 0bf1b7829042bec47b84061c5f6168b354731e33)
1*0bf1b782SLei YU /**
2*0bf1b782SLei YU  * Copyright © 2019 IBM Corporation
3*0bf1b782SLei YU  *
4*0bf1b782SLei YU  * Licensed under the Apache License, Version 2.0 (the "License");
5*0bf1b782SLei YU  * you may not use this file except in compliance with the License.
6*0bf1b782SLei YU  * You may obtain a copy of the License at
7*0bf1b782SLei YU  *
8*0bf1b782SLei YU  *     http://www.apache.org/licenses/LICENSE-2.0
9*0bf1b782SLei YU  *
10*0bf1b782SLei YU  * Unless required by applicable law or agreed to in writing, software
11*0bf1b782SLei YU  * distributed under the License is distributed on an "AS IS" BASIS,
12*0bf1b782SLei YU  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*0bf1b782SLei YU  * See the License for the specific language governing permissions and
14*0bf1b782SLei YU  * limitations under the License.
15*0bf1b782SLei YU  */
16*0bf1b782SLei YU #include "config.h"
17*0bf1b782SLei YU 
18*0bf1b782SLei YU #include "version.hpp"
19*0bf1b782SLei YU 
20*0bf1b782SLei YU #include "pmbus.hpp"
21*0bf1b782SLei YU #include "utility.hpp"
22*0bf1b782SLei YU 
23*0bf1b782SLei YU #include <phosphor-logging/log.hpp>
24*0bf1b782SLei YU #include <tuple>
25*0bf1b782SLei YU 
26*0bf1b782SLei YU using json = nlohmann::json;
27*0bf1b782SLei YU 
28*0bf1b782SLei YU using namespace phosphor::logging;
29*0bf1b782SLei YU 
30*0bf1b782SLei YU // PsuInfo contains the device path, pmbus read type, and the version string
31*0bf1b782SLei YU using PsuVersionInfo =
32*0bf1b782SLei YU     std::tuple<std::string, phosphor::pmbus::Type, std::string>;
33*0bf1b782SLei YU 
34*0bf1b782SLei YU namespace utils
35*0bf1b782SLei YU {
36*0bf1b782SLei YU PsuVersionInfo getVersionInfo(const std::string& psuInventoryPath)
37*0bf1b782SLei YU {
38*0bf1b782SLei YU     auto data = phosphor::power::util::loadJSONFromFile(PSU_JSON_PATH);
39*0bf1b782SLei YU 
40*0bf1b782SLei YU     if (data == nullptr)
41*0bf1b782SLei YU     {
42*0bf1b782SLei YU         return {};
43*0bf1b782SLei YU     }
44*0bf1b782SLei YU 
45*0bf1b782SLei YU     auto devices = data.find("psuDevices");
46*0bf1b782SLei YU     if (devices == data.end())
47*0bf1b782SLei YU     {
48*0bf1b782SLei YU         log<level::WARNING>("Unable to find psuDevices");
49*0bf1b782SLei YU         return {};
50*0bf1b782SLei YU     }
51*0bf1b782SLei YU     auto devicePath = devices->find(psuInventoryPath);
52*0bf1b782SLei YU     if (devicePath == devices->end())
53*0bf1b782SLei YU     {
54*0bf1b782SLei YU         log<level::WARNING>("Unable to find path for PSU",
55*0bf1b782SLei YU                             entry("PATH=%s", psuInventoryPath.c_str()));
56*0bf1b782SLei YU         return {};
57*0bf1b782SLei YU     }
58*0bf1b782SLei YU 
59*0bf1b782SLei YU     auto type = phosphor::power::util::getPMBusAccessType(data);
60*0bf1b782SLei YU 
61*0bf1b782SLei YU     std::string versionStr;
62*0bf1b782SLei YU     for (const auto& fru : data["fruConfigs"])
63*0bf1b782SLei YU     {
64*0bf1b782SLei YU         if (fru["propertyName"] == "Version")
65*0bf1b782SLei YU         {
66*0bf1b782SLei YU             versionStr = fru["fileName"];
67*0bf1b782SLei YU             break;
68*0bf1b782SLei YU         }
69*0bf1b782SLei YU     }
70*0bf1b782SLei YU     if (versionStr.empty())
71*0bf1b782SLei YU     {
72*0bf1b782SLei YU         log<level::WARNING>("Unable to find Version file");
73*0bf1b782SLei YU         return {};
74*0bf1b782SLei YU     }
75*0bf1b782SLei YU     return std::make_tuple(*devicePath, type, versionStr);
76*0bf1b782SLei YU }
77*0bf1b782SLei YU } // namespace utils
78*0bf1b782SLei YU 
79*0bf1b782SLei YU namespace version
80*0bf1b782SLei YU {
81*0bf1b782SLei YU 
82*0bf1b782SLei YU std::string getVersion(const std::string& psuInventoryPath)
83*0bf1b782SLei YU {
84*0bf1b782SLei YU     const auto& [devicePath, type, versionStr] =
85*0bf1b782SLei YU         utils::getVersionInfo(psuInventoryPath);
86*0bf1b782SLei YU     if (devicePath.empty() || versionStr.empty())
87*0bf1b782SLei YU     {
88*0bf1b782SLei YU         return {};
89*0bf1b782SLei YU     }
90*0bf1b782SLei YU     std::string version;
91*0bf1b782SLei YU     try
92*0bf1b782SLei YU     {
93*0bf1b782SLei YU         phosphor::pmbus::PMBus pmbus(devicePath);
94*0bf1b782SLei YU         version = pmbus.readString(versionStr, type);
95*0bf1b782SLei YU     }
96*0bf1b782SLei YU     catch (const std::exception& ex)
97*0bf1b782SLei YU     {
98*0bf1b782SLei YU         log<level::ERR>(ex.what());
99*0bf1b782SLei YU     }
100*0bf1b782SLei YU     return version;
101*0bf1b782SLei YU }
102*0bf1b782SLei YU 
103*0bf1b782SLei YU } // namespace version
104