blob: 787556431fe0d39ab7da6d0f3c2dbb0e0c447ac7 [file] [log] [blame]
Shawn McCarney0fbc2f62024-11-05 17:01:53 -06001/**
2 * Copyright © 2024 IBM 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#include "config.h"
17
18#include "model.hpp"
19
20#include "pmbus.hpp"
21#include "utility.hpp"
22#include "utils.hpp"
23
24#include <nlohmann/json.hpp>
Anwaar Hadi72e584c2025-05-20 22:02:14 +000025#include <phosphor-logging/lg2.hpp>
Shawn McCarney0fbc2f62024-11-05 17:01:53 -060026
27#include <exception>
28#include <format>
29#include <fstream>
30#include <stdexcept>
31
32using json = nlohmann::json;
33
34using namespace utils;
Shawn McCarney0fbc2f62024-11-05 17:01:53 -060035using namespace phosphor::power::util;
36
37namespace model
38{
39
40namespace internal
41{
42
43/**
44 * @brief Get the PSU model from sysfs.
45 *
46 * Obtain PSU information from the PSU JSON file.
47 *
48 * Throws an exception if an error occurs.
49 *
50 * @param[in] psuInventoryPath - PSU D-Bus inventory path
51 *
52 * @return PSU model
53 */
54std::string getModelJson(const std::string& psuInventoryPath)
55{
56 // Parse PSU JSON file
57 std::ifstream file{PSU_JSON_PATH};
58 json data = json::parse(file);
59
60 // Get PSU device path from JSON
61 auto it = data.find("psuDevices");
62 if (it == data.end())
63 {
64 throw std::runtime_error{"Unable to find psuDevices"};
65 }
66 auto device = it->find(psuInventoryPath);
67 if (device == it->end())
68 {
69 throw std::runtime_error{std::format(
70 "Unable to find device path for PSU {}", psuInventoryPath)};
71 }
72 std::string devicePath = *device;
73 if (devicePath.empty())
74 {
75 throw std::runtime_error{
76 std::format("Empty device path for PSU {}", psuInventoryPath)};
77 }
78
79 // Get sysfs filename from JSON for Model information
80 it = data.find("fruConfigs");
81 if (it == data.end())
82 {
83 throw std::runtime_error{"Unable to find fruConfigs"};
84 }
85 std::string fileName;
86 for (const auto& fru : *it)
87 {
88 if (fru.contains("propertyName") && (fru["propertyName"] == "Model") &&
89 fru.contains("fileName"))
90 {
91 fileName = fru["fileName"];
92 break;
93 }
94 }
95 if (fileName.empty())
96 {
97 throw std::runtime_error{"Unable to find file name for Model"};
98 }
99
100 // Get PMBus access type from JSON
101 phosphor::pmbus::Type type = getPMBusAccessType(data);
102
103 // Read model from sysfs file
104 phosphor::pmbus::PMBus pmbus(devicePath);
105 std::string model = pmbus.readString(fileName, type);
106 return model;
107}
108
109/**
110 * @brief Get the PSU model from sysfs.
111 *
112 * Obtain PSU information from D-Bus.
113 *
114 * Throws an exception if an error occurs.
115 *
116 * @param[in] bus - D-Bus connection
117 * @param[in] psuInventoryPath - PSU D-Bus inventory path
118 *
119 * @return PSU model
120 */
121std::string getModelDbus(sdbusplus::bus_t& bus,
122 const std::string& psuInventoryPath)
123{
124 // Get PSU I2C bus/address and create PMBus interface
125 const auto [i2cBus, i2cAddr] = getPsuI2c(bus, psuInventoryPath);
126 auto pmbus = getPmbusIntf(i2cBus, i2cAddr);
127
128 // Read model from sysfs file
129 std::string fileName = "ccin";
130 auto type = phosphor::pmbus::Type::HwmonDeviceDebug;
131 std::string model = pmbus->readString(fileName, type);
132 return model;
133}
134
135} // namespace internal
136
137std::string getModel(sdbusplus::bus_t& bus, const std::string& psuInventoryPath)
138{
139 std::string model;
140 try
141 {
Shawn McCarney23dee382024-11-11 18:41:49 -0600142 if (usePsuJsonFile())
Shawn McCarney0fbc2f62024-11-05 17:01:53 -0600143 {
144 // Obtain PSU information from JSON file
145 model = internal::getModelJson(psuInventoryPath);
146 }
147 else
148 {
149 // Obtain PSU information from D-Bus
150 model = internal::getModelDbus(bus, psuInventoryPath);
151 }
152 }
153 catch (const std::exception& e)
154 {
Anwaar Hadi72e584c2025-05-20 22:02:14 +0000155 lg2::error("Error in getModel: {ERROR}", "ERROR", e);
Shawn McCarney0fbc2f62024-11-05 17:01:53 -0600156 }
157 return model;
158}
159
160} // namespace model