psutils: Move functions from updater to utils
Move common, utility functions from updater.*pp to utils.*pp. This will
enable those functions to be used by other command line options in the
psutils tool.
Modify --get-version and --get-model to use the new utility functions.
Also update --get-version to provide a single getVersion() function that
handles the existence of the psu.json file as a low-level implementation
detail.
Tested:
* Verified all automated tests run successfully
* Verified --get-version still works
* With psu.json file
* Without psu.json file
* Verified --get-model still works
* With psu.json file
* Without psu.json file
* Verified --update still gets correct device path, device name, and I2C
bus/address from functions that moved to utils.*pp
* The complete test plan is available at
https://gist.github.com/smccarney/c049e24655d32e22cab9d521d145774a
Change-Id: I51ceca10957dc9a924d0d7516dc29632a6ed82d3
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/tools/power-utils/utils.cpp b/tools/power-utils/utils.cpp
index 0afc4a8..e70004d 100644
--- a/tools/power-utils/utils.cpp
+++ b/tools/power-utils/utils.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "config.h"
+
#include "utils.hpp"
#include "utility.hpp"
@@ -20,14 +22,21 @@
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/Device/error.hpp>
+#include <cassert>
#include <exception>
+#include <filesystem>
+#include <format>
+#include <iomanip>
+#include <ios>
#include <iostream>
#include <regex>
+#include <sstream>
#include <stdexcept>
using namespace phosphor::logging;
using namespace phosphor::power::util;
using namespace sdbusplus::xyz::openbmc_project::Common::Device::Error;
+namespace fs = std::filesystem;
namespace utils
{
@@ -165,4 +174,73 @@
return false;
}
+std::string getDeviceName(std::string devPath)
+{
+ if (devPath.back() == '/')
+ {
+ devPath.pop_back();
+ }
+ return fs::path(devPath).stem().string();
+}
+
+std::string getDevicePath(sdbusplus::bus_t& bus,
+ const std::string& psuInventoryPath)
+{
+ try
+ {
+ if (usePsuJsonFile())
+ {
+ auto data = loadJSONFromFile(PSU_JSON_PATH);
+ if (data == nullptr)
+ {
+ return {};
+ }
+ auto devicePath = data["psuDevices"][psuInventoryPath];
+ if (devicePath.empty())
+ {
+ log<level::WARNING>("Unable to find psu devices or path");
+ }
+ return devicePath;
+ }
+ else
+ {
+ const auto [i2cbus, i2caddr] = getPsuI2c(bus, psuInventoryPath);
+ const auto DevicePath = "/sys/bus/i2c/devices/";
+ std::ostringstream ss;
+ ss << std::hex << std::setw(4) << std::setfill('0') << i2caddr;
+ std::string addrStr = ss.str();
+ std::string busStr = std::to_string(i2cbus);
+ std::string devPath = DevicePath + busStr + "-" + addrStr;
+ return devPath;
+ }
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(
+ std::format("Error in getDevicePath: {}", e.what()).c_str());
+ return {};
+ }
+ catch (...)
+ {
+ log<level::ERR>("Unknown error occurred in getDevicePath");
+ return {};
+ }
+}
+
+std::pair<uint8_t, uint8_t> parseDeviceName(const std::string& devName)
+{
+ // Get I2C bus and device address, e.g. 3-0068
+ // is parsed to bus 3, device address 0x68
+ auto pos = devName.find('-');
+ assert(pos != std::string::npos);
+ uint8_t busId = std::stoi(devName.substr(0, pos));
+ uint8_t devAddr = std::stoi(devName.substr(pos + 1), nullptr, 16);
+ return {busId, devAddr};
+}
+
+bool usePsuJsonFile()
+{
+ return checkFileExists(PSU_JSON_PATH);
+}
+
} // namespace utils