Un-expanded to expanded location code conversion
This commit implements an api to get expanded location code
from a given un-expanded location code and node number.
In case invalid argument is passed or the location code is
not found, corresponding error is returned to the caller.
Tested on simics.
To build use following command.
meson -Dibm-parser=enabled -Dvpd-manager=enabled build
ninja -C build
Sample bus call.
busctl call com.ibm.VPD.Manager /com/ibm/VPD/Manager com.ibm.VPD.Manager
GetExpandedLocationCode sq <locationCode> <nodeNumber>.
Signed-off-by: SunnySrivastava1984 <sunnsr25@in.ibm.com>
Change-Id: I52654a1c34d25dc9b861159a2ae1d15379b44677
diff --git a/const.hpp b/const.hpp
index a7338d4..fc93468 100644
--- a/const.hpp
+++ b/const.hpp
@@ -42,6 +42,7 @@
constexpr int IPZ_DATA_START = 11;
constexpr uint8_t KW_VAL_PAIR_START_TAG = 0x84;
constexpr uint8_t RECORD_END_TAG = 0x78;
+constexpr int UNEXP_LOCATION_CODE_MIN_LENGTH = 4;
namespace lengths
{
diff --git a/types.hpp b/types.hpp
index 2b6dd06..bab4569 100644
--- a/types.hpp
+++ b/types.hpp
@@ -36,6 +36,8 @@
using FruIsMotherboard = bool;
using FrusMap =
std::unordered_map<Path, std::pair<VPDfilepath, FruIsMotherboard>>;
+using LocationCode = std::string;
+using LocationCodeMap = std::unordered_map<Path, LocationCode>;
using namespace std::string_literals;
constexpr auto pimPath = "/xyz/openbmc_project/inventory";
diff --git a/utils.cpp b/utils.cpp
index 558e728..6002b9c 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -132,14 +132,17 @@
auto result = bus.call(properties);
if (!result.is_method_error())
{
- variant<Binary> val;
+ variant<Binary, string> val;
result.read(val);
-
if (auto pVal = get_if<Binary>(&val))
{
propVal.assign(reinterpret_cast<const char*>(pVal->data()),
pVal->size());
}
+ else if (auto pVal = get_if<string>(&val))
+ {
+ propVal.assign(pVal->data(), pVal->size());
+ }
}
return propVal;
}
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index 61a392a..1ce1cd1 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -4,9 +4,11 @@
#include "editor_impl.hpp"
#include "parser.hpp"
+#include "reader_impl.hpp"
using namespace openpower::vpd::constants;
using namespace openpower::vpd::manager::editor;
+using namespace openpower::vpd::manager::reader;
namespace openpower
{
@@ -75,6 +77,12 @@
frus.emplace(itemEEPROM["inventoryPath"]
.get_ref<const nlohmann::json::string_t&>(),
std::make_pair(itemFRUS.key(), isMotherboard));
+
+ fruLocationCode.emplace(
+ itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]["LocationCode"]
+ .get_ref<const nlohmann::json::string_t&>(),
+ itemEEPROM["inventoryPath"]
+ .get_ref<const nlohmann::json::string_t&>());
}
}
}
@@ -134,7 +142,9 @@
std::string Manager::getExpandedLocationCode(const std::string locationCode,
const uint16_t nodeNumber)
{
- // implement the interface
+ ReaderImpl read;
+ return read.getExpandedLocationCode(locationCode, nodeNumber,
+ fruLocationCode);
}
} // namespace manager
diff --git a/vpd-manager/manager.hpp b/vpd-manager/manager.hpp
index e5882b5..455cd11 100644
--- a/vpd-manager/manager.hpp
+++ b/vpd-manager/manager.hpp
@@ -104,7 +104,7 @@
getFRUsByExpandedLocationCode(const std::string locationCode);
/** @brief Implementation for GetExpandedLocationCode
- * An api to get expanded location code corresponding to a given
+ * An API to get expanded location code corresponding to a given
* un-expanded location code.
*
* @param[in] locationCode - Location code in un-expaned format.
@@ -136,6 +136,9 @@
// map to hold mapping to inventory path to vpd file path
// we need as map here as it is in reverse order to that of json
inventory::FrusMap frus;
+
+ // map to hold the mapping of location code and inventory path
+ inventory::LocationCodeMap fruLocationCode;
};
} // namespace manager
diff --git a/vpd-manager/meson.build b/vpd-manager/meson.build
index 44b34aa..7255dad 100644
--- a/vpd-manager/meson.build
+++ b/vpd-manager/meson.build
@@ -9,6 +9,7 @@
'server.cpp',
'error.cpp',
'editor_impl.cpp',
+ 'reader_impl.cpp',
'../impl.cpp',
'../parser.cpp',
'../utils.cpp',
diff --git a/vpd-manager/reader_impl.cpp b/vpd-manager/reader_impl.cpp
new file mode 100644
index 0000000..21660d9
--- /dev/null
+++ b/vpd-manager/reader_impl.cpp
@@ -0,0 +1,60 @@
+#include "reader_impl.hpp"
+
+#include "utils.hpp"
+
+#include <com/ibm/VPD/error.hpp>
+#include <map>
+#include <phosphor-logging/elog-errors.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace openpower
+{
+namespace vpd
+{
+namespace manager
+{
+namespace reader
+{
+
+using namespace phosphor::logging;
+using namespace openpower::vpd::inventory;
+using namespace openpower::vpd::constants;
+
+using InvalidArgument =
+ sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
+using LocationNotFound = sdbusplus::com::ibm::VPD::Error::LocationNotFound;
+
+std::string ReaderImpl::getExpandedLocationCode(
+ const std::string& locationCode, const uint16_t& nodeNumber,
+ const LocationCodeMap& frusLocationCode) const
+{
+ if ((locationCode.length() < UNEXP_LOCATION_CODE_MIN_LENGTH) ||
+ ((locationCode.find("fcs", 1, 3) == std::string::npos) &&
+ (locationCode.find("mts", 1, 3) == std::string::npos)))
+ {
+ // argument is not valid
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
+ Argument::ARGUMENT_VALUE(locationCode.c_str()));
+ }
+
+ auto iterator = frusLocationCode.find(locationCode);
+ if (iterator == frusLocationCode.end())
+ {
+ // TODO: Implementation of error logic till then throwing invalid
+ // argument
+ // the location code was not found in the system
+ // elog<LocationNotFound>();
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
+ Argument::ARGUMENT_VALUE(locationCode.c_str()));
+ }
+
+ std::string expandedLocationCode =
+ readBusProperty(iterator->second, LOCATION_CODE_INF, "LocationCode");
+ return expandedLocationCode;
+}
+
+} // namespace reader
+} // namespace manager
+} // namespace vpd
+} // namespace openpower
diff --git a/vpd-manager/reader_impl.hpp b/vpd-manager/reader_impl.hpp
index d9ceafe..17cfc75 100644
--- a/vpd-manager/reader_impl.hpp
+++ b/vpd-manager/reader_impl.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "types.hpp"
+
namespace openpower
{
namespace vpd
@@ -12,8 +14,6 @@
/** @class ReaderImpl
* @brief Implements functionalities related to reading of VPD related data
* from the system.
- *
- * A parsed vpd inventory json file is required to construct the class.
*/
class ReaderImpl
{
@@ -24,6 +24,18 @@
ReaderImpl(ReaderImpl&&) = delete;
ReaderImpl& operator=(ReaderImpl&&) = delete;
~ReaderImpl() = default;
+
+ /** @brief An API to expand a given unexpanded location code.
+ * @param[in] locationCode - unexpanded location code.
+ * @param[in] nodeNumber - node on which we are looking for location code.
+ * @param[in] frusLocationCode - mapping of inventory path and location
+ * code.
+ * @return Expanded location code.
+ */
+ std::string getExpandedLocationCode(
+ const std::string& locationCode, const uint16_t& nodeNumber,
+ const inventory::LocationCodeMap& frusLocationCode) const;
+
}; // class ReaderImpl
} // namespace reader