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/updater.cpp b/tools/power-utils/updater.cpp
index dab0460..c48decb 100644
--- a/tools/power-utils/updater.cpp
+++ b/tools/power-utils/updater.cpp
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "config.h"
-
 #include "updater.hpp"
 
 #include "pmbus.hpp"
@@ -22,8 +20,6 @@
 #include "utility.hpp"
 #include "utils.hpp"
 
-#include <sys/stat.h>
-
 #include <phosphor-logging/log.hpp>
 
 #include <chrono>
@@ -44,75 +40,6 @@
 constexpr uint8_t CRC8_POLYNOMIAL = 0x07;
 constexpr uint8_t CRC8_INITIAL = 0x00;
 
-/* Get the device name from the device path */
-std::string getDeviceName(std::string devPath)
-{
-    if (devPath.back() == '/')
-    {
-        devPath.pop_back();
-    }
-    return fs::path(devPath).stem().string();
-}
-
-// Construct the device path using the I2C bus and address or read inventory
-// path
-std::string getDevicePath(sdbusplus::bus_t& bus,
-                          const std::string& psuInventoryPath)
-{
-    try
-    {
-        if (internal::usePsuJsonFile())
-        {
-            auto data = util::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] =
-                utils::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 {};
-    }
-}
-
-// Parse the device name to get I2C bus and address
-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};
-}
-
 // Get the appropriate Updater class instance based PSU model number
 std::unique_ptr<updater::Updater> getClassInstance(
     const std::string& model, const std::string& psuInventoryPath,
@@ -250,17 +177,12 @@
     return readDataBytes;
 }
 
-// Wrapper to check existence of PSU JSON file.
-bool usePsuJsonFile()
-{
-    return utils::checkFileExists(PSU_JSON_PATH);
-}
 } // namespace internal
 
 bool update(sdbusplus::bus_t& bus, const std::string& psuInventoryPath,
             const std::string& imageDir)
 {
-    auto devPath = internal::getDevicePath(bus, psuInventoryPath);
+    auto devPath = utils::getDevicePath(bus, psuInventoryPath);
 
     if (devPath.empty())
     {
@@ -289,8 +211,7 @@
 Updater::Updater(const std::string& psuInventoryPath,
                  const std::string& devPath, const std::string& imageDir) :
     bus(sdbusplus::bus::new_default()), psuInventoryPath(psuInventoryPath),
-    devPath(devPath), devName(internal::getDeviceName(devPath)),
-    imageDir(imageDir)
+    devPath(devPath), devName(utils::getDeviceName(devPath)), imageDir(imageDir)
 {
     fs::path p = fs::path(devPath) / "driver";
     try
@@ -397,7 +318,7 @@
         // directly read the debugfs to get the status.
         try
         {
-            auto path = internal::getDevicePath(bus, p);
+            auto path = utils::getDevicePath(bus, p);
             PMBus pmbus(path);
             uint16_t statusWord = pmbus.read(STATUS_WORD, Type::Debug);
             auto status0Vout = pmbus.insertPageNum(STATUS_VOUT, 0);
@@ -457,7 +378,7 @@
 
 void Updater::createI2CDevice()
 {
-    auto [id, addr] = internal::parseDeviceName(devName);
+    auto [id, addr] = utils::parseDeviceName(devName);
     i2c = i2c::create(id, addr);
 }
 } // namespace updater