PEL: Add Symbolic FRU support to Callout
This adds a constructor that takes a priority, symbolic FRU, location
cod, and if the location code can be trusted enough that the FRU can be
replaced based on it. It then creates a FRUIdentity object with the
symbolic FRU.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I38074467dd5dba6f9260d50afe93e08c7fe96cd2
diff --git a/extensions/openpower-pels/callout.cpp b/extensions/openpower-pels/callout.cpp
index 66181ff..a477803 100644
--- a/extensions/openpower-pels/callout.cpp
+++ b/extensions/openpower-pels/callout.cpp
@@ -108,6 +108,22 @@
_size = flattenedSize();
}
+Callout::Callout(CalloutPriority priority,
+ const std::string& symbolicFRUFromRegistry,
+ const std::string& locationCode, bool trustedLocationCode)
+{
+ _flags = calloutType | fruIdentIncluded;
+
+ _priority = static_cast<uint8_t>(priority);
+
+ setLocationCode(locationCode);
+
+ _fruIdentity = std::make_unique<FRUIdentity>(symbolicFRUFromRegistry,
+ trustedLocationCode);
+
+ _size = flattenedSize();
+}
+
void Callout::setLocationCode(const std::string& locationCode)
{
if (locationCode.empty())
diff --git a/extensions/openpower-pels/callout.hpp b/extensions/openpower-pels/callout.hpp
index 6b7dbc7..fda0024 100644
--- a/extensions/openpower-pels/callout.hpp
+++ b/extensions/openpower-pels/callout.hpp
@@ -84,7 +84,7 @@
* @brief Constructor
*
* Creates the objects with a FRUIdentity substructure that calls
- * out maintenance procedure.
+ * out a maintenance procedure.
*
* @param[in] priority - The priority of the callout
* @param[in] procedureFromRegistry - The maintenance procedure name
@@ -93,6 +93,22 @@
Callout(CalloutPriority priority, const std::string& procedureFromRegistry);
/**
+ * @brief Constructor
+ *
+ * Creates the objects with a FRUIdentity substructure that calls
+ * out a symbolic FRU.
+ *
+ * @param[in] priority - The priority of the callout
+ * @param[in] symbolicFRUFromRegistry - The symbolic FRU name as
+ * defined in the message registry.
+ * @param[in] locationCode - The location code of the callout
+ * @param[in] trustedLocationCode - If the location is trusted
+ */
+ Callout(CalloutPriority priority,
+ const std::string& symbolicFRUFromRegistry,
+ const std::string& locationCode, bool trustedLocationCode);
+
+ /**
* @brief Returns the size of this object when flattened into a PEL
*
* @return size_t - The size of the section
diff --git a/test/openpower-pels/src_callout_test.cpp b/test/openpower-pels/src_callout_test.cpp
index 68090f7..74c396c 100644
--- a/test/openpower-pels/src_callout_test.cpp
+++ b/test/openpower-pels/src_callout_test.cpp
@@ -318,3 +318,70 @@
auto& newFRU = newCallout.fruIdentity();
EXPECT_EQ(newFRU->getMaintProc().value(), fru->getMaintProc().value());
}
+
+// Create a callout object by passing in the symbolic FRU to add.
+TEST(CalloutTest, TestSymbolicFRUCallout)
+{
+ // symbolic FRU with a location code
+ {
+ Callout callout{CalloutPriority::high, "service_docs", "P1-C3", false};
+
+ // size/flags/pri/locsize fields + plus loc + FRUIdentity size
+ size_t size = 4 + 8 + 12;
+
+ EXPECT_EQ(callout.flags(),
+ Callout::calloutType | Callout::fruIdentIncluded);
+
+ EXPECT_EQ(callout.flattenedSize(), size);
+ EXPECT_EQ(callout.priority(), 'H');
+ EXPECT_EQ(callout.locationCode(), "P1-C3");
+ EXPECT_EQ(callout.locationCodeSize(), 8);
+
+ auto& fru = callout.fruIdentity();
+
+ EXPECT_EQ(fru->failingComponentType(), FRUIdentity::symbolicFRU);
+ EXPECT_EQ(fru->getPN().value(), "SVCDOCS");
+ }
+
+ // symbolic FRU without a location code
+ {
+ Callout callout{CalloutPriority::high, "service_docs", "", false};
+
+ // size/flags/pri/locsize fields + plus loc + FRUIdentity size
+ size_t size = 4 + 0 + 12;
+
+ EXPECT_EQ(callout.flags(),
+ Callout::calloutType | Callout::fruIdentIncluded);
+
+ EXPECT_EQ(callout.flattenedSize(), size);
+ EXPECT_EQ(callout.priority(), 'H');
+ EXPECT_EQ(callout.locationCode(), "");
+ EXPECT_EQ(callout.locationCodeSize(), 0);
+
+ auto& fru = callout.fruIdentity();
+
+ EXPECT_EQ(fru->failingComponentType(), FRUIdentity::symbolicFRU);
+ EXPECT_EQ(fru->getPN().value(), "SVCDOCS");
+ }
+
+ // symbolic FRU with a trusted location code
+ {
+ Callout callout{CalloutPriority::high, "service_docs", "P1-C3", true};
+
+ // size/flags/pri/locsize fields + plus loc + FRUIdentity size
+ size_t size = 4 + 8 + 12;
+
+ EXPECT_EQ(callout.flags(),
+ Callout::calloutType | Callout::fruIdentIncluded);
+
+ EXPECT_EQ(callout.flattenedSize(), size);
+ EXPECT_EQ(callout.priority(), 'H');
+ EXPECT_EQ(callout.locationCode(), "P1-C3");
+ EXPECT_EQ(callout.locationCodeSize(), 8);
+
+ auto& fru = callout.fruIdentity();
+ EXPECT_EQ(fru->failingComponentType(),
+ FRUIdentity::symbolicFRUTrustedLocCode);
+ EXPECT_EQ(fru->getPN().value(), "SVCDOCS");
+ }
+}