PEL: Extract MRUs from callout JSON
The callout JSON can also contain MRU (Manufacturing Replaceable Unit)
IDs and priorities that should be added to a callout along with the FRU.
Extract them from the JSON and add them to the callout if they are
there.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I25b801d5fd4371719d7a4f39056cdc3d2bf29dfb
diff --git a/extensions/openpower-pels/src.cpp b/extensions/openpower-pels/src.cpp
index 6462598..1861608 100644
--- a/extensions/openpower-pels/src.cpp
+++ b/extensions/openpower-pels/src.cpp
@@ -754,7 +754,8 @@
void SRC::addInventoryCallout(const std::string& inventoryPath,
const std::optional<CalloutPriority>& priority,
const std::optional<std::string>& locationCode,
- const DataInterfaceBase& dataIface)
+ const DataInterfaceBase& dataIface,
+ const std::vector<src::MRU::MRUCallout>& mrus)
{
std::string locCode;
std::string fn;
@@ -781,7 +782,8 @@
CalloutPriority p =
priority ? priority.value() : CalloutPriority::high;
- callout = std::make_unique<src::Callout>(p, locCode, fn, ccin, sn);
+ callout =
+ std::make_unique<src::Callout>(p, locCode, fn, ccin, sn, mrus);
}
catch (const SdBusError& e)
{
@@ -790,8 +792,8 @@
addDebugData(msg);
// Just create the callout with empty FRU fields
- callout = std::make_unique<src::Callout>(CalloutPriority::high,
- locCode, fn, ccin, sn);
+ callout = std::make_unique<src::Callout>(
+ CalloutPriority::high, locCode, fn, ccin, sn, mrus);
}
}
catch (const SdBusError& e)
@@ -800,8 +802,6 @@
": " + e.what();
addDebugData(msg);
- // If this were to happen, people would have to look in the UserData
- // section that contains CALLOUT_INVENTORY_PATH to see what failed.
callout = std::make_unique<src::Callout>(CalloutPriority::high,
"no_vpd_for_fru");
}
@@ -1116,6 +1116,7 @@
{
// A hardware FRU
std::string inventoryPath;
+ std::vector<src::MRU::MRUCallout> mrus;
if (jsonCallout.contains("InventoryPath"))
{
@@ -1143,6 +1144,11 @@
}
}
+ if (jsonCallout.contains("MRUs"))
+ {
+ mrus = getMRUsFromJSON(jsonCallout.at("MRUs"));
+ }
+
// If the location code was also passed in, use that here too
// so addInventoryCallout doesn't have to look it up.
std::optional<std::string> lc;
@@ -1151,7 +1157,7 @@
lc = locCode;
}
- addInventoryCallout(inventoryPath, priority, lc, dataIface);
+ addInventoryCallout(inventoryPath, priority, lc, dataIface, mrus);
}
if (callout)
@@ -1187,5 +1193,43 @@
return priority;
}
+std::vector<src::MRU::MRUCallout>
+ SRC::getMRUsFromJSON(const nlohmann::json& mruJSON)
+{
+ std::vector<src::MRU::MRUCallout> mrus;
+
+ // Looks like:
+ // [
+ // {
+ // "ID": 100,
+ // "Priority": "H"
+ // }
+ // ]
+ if (!mruJSON.is_array())
+ {
+ addDebugData("MRU callout JSON is not an array");
+ return mrus;
+ }
+
+ for (const auto& mruCallout : mruJSON)
+ {
+ try
+ {
+ auto priority = getPriorityFromJSON(mruCallout);
+ auto id = mruCallout.at("ID").get<uint32_t>();
+
+ src::MRU::MRUCallout mru{static_cast<uint32_t>(priority), id};
+ mrus.push_back(std::move(mru));
+ }
+ catch (const std::exception& e)
+ {
+ addDebugData(fmt::format("Invalid MRU entry in JSON: {}: {}",
+ mruCallout.dump(), e.what()));
+ }
+ }
+
+ return mrus;
+}
+
} // namespace pels
} // namespace openpower
diff --git a/extensions/openpower-pels/src.hpp b/extensions/openpower-pels/src.hpp
index 0ec01f6..9757a92 100644
--- a/extensions/openpower-pels/src.hpp
+++ b/extensions/openpower-pels/src.hpp
@@ -384,11 +384,14 @@
* @param[in] priority - An optional priority (uses high if nullopt)
* @param[in] locationCode - The expanded location code (or look it up)
* @param[in] dataIface - The DataInterface object
+ * @param[in] mrus - The MRUs to add to the callout
*/
- void addInventoryCallout(const std::string& inventoryPath,
- const std::optional<CalloutPriority>& priority,
- const std::optional<std::string>& locationCode,
- const DataInterfaceBase& dataIface);
+ void
+ addInventoryCallout(const std::string& inventoryPath,
+ const std::optional<CalloutPriority>& priority,
+ const std::optional<std::string>& locationCode,
+ const DataInterfaceBase& dataIface,
+ const std::vector<src::MRU::MRUCallout>& mrus = {});
/**
* @brief Adds FRU callouts based on the registry entry JSON
@@ -462,6 +465,15 @@
CalloutPriority getPriorityFromJSON(const nlohmann::json& json);
/**
+ * @brief Exracts MRU values and their priorities from the
+ * input JSON array.
+ *
+ * @param[in] mruJSON - The JSON array
+ */
+ std::vector<src::MRU::MRUCallout>
+ getMRUsFromJSON(const nlohmann::json& mruJSON);
+
+ /**
* @brief The SRC version field
*/
uint8_t _version;
diff --git a/test/openpower-pels/src_test.cpp b/test/openpower-pels/src_test.cpp
index c4b80a4..5795ece 100644
--- a/test/openpower-pels/src_test.cpp
+++ b/test/openpower-pels/src_test.cpp
@@ -990,6 +990,15 @@
EXPECT_EQ(fru->getCCIN().value(), "CCCC");
EXPECT_EQ(fru->getSN().value(), "123456789ABC");
EXPECT_EQ(fru->failingComponentType(), src::FRUIdentity::hardwareFRU);
+
+ auto& mruCallouts = callouts[0]->mru();
+ ASSERT_TRUE(mruCallouts);
+ auto& mrus = mruCallouts->mrus();
+ ASSERT_EQ(mrus.size(), 2);
+ EXPECT_EQ(mrus[0].id, 42);
+ EXPECT_EQ(mrus[0].priority, 'H');
+ EXPECT_EQ(mrus[1].id, 43);
+ EXPECT_EQ(mrus[1].priority, 'M');
}
// Check callout 1