PEL: Add Callout object constructors
Add constructors to the PEL Callout object to create a FRU callout,
either a hardware FRU with PN/SN/CCIN, or a maintenance procedure.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I015370fbfa4e5522eada316d12c10b130e1de4be
diff --git a/extensions/openpower-pels/callout.cpp b/extensions/openpower-pels/callout.cpp
index 95c6408..905c212 100644
--- a/extensions/openpower-pels/callout.cpp
+++ b/extensions/openpower-pels/callout.cpp
@@ -26,6 +26,8 @@
using namespace phosphor::logging;
+constexpr size_t locationCodeMaxSize = 80;
+
Callout::Callout(Stream& pel)
{
pel >> _size >> _flags >> _priority >> _locationCodeSize;
@@ -76,7 +78,67 @@
}
}
-size_t Callout::flattenedSize()
+Callout::Callout(CalloutPriority priority, const std::string& locationCode,
+ const std::string& partNumber, const std::string& ccin,
+ const std::string& serialNumber)
+{
+ _flags = calloutType | fruIdentIncluded;
+
+ _priority = static_cast<uint8_t>(priority);
+
+ setLocationCode(locationCode);
+
+ _fruIdentity =
+ std::make_unique<FRUIdentity>(partNumber, ccin, serialNumber);
+
+ _size = flattenedSize();
+}
+
+Callout::Callout(CalloutPriority priority, MaintProcedure procedure)
+{
+ _flags = calloutType | fruIdentIncluded;
+
+ _priority = static_cast<uint8_t>(priority);
+
+ _locationCodeSize = 0;
+
+ _fruIdentity = std::make_unique<FRUIdentity>(procedure);
+
+ _size = flattenedSize();
+}
+
+void Callout::setLocationCode(const std::string& locationCode)
+{
+ if (locationCode.empty())
+ {
+ _locationCodeSize = 0;
+ return;
+ }
+
+ std::copy(locationCode.begin(), locationCode.end(),
+ std::back_inserter(_locationCode));
+
+ if (_locationCode.size() < locationCodeMaxSize)
+ {
+ // Add a NULL, and then pad to a 4B boundary
+ _locationCode.push_back('\0');
+
+ while (_locationCode.size() % 4)
+ {
+ _locationCode.push_back('\0');
+ }
+ }
+ else
+ {
+ // Too big - truncate it and ensure it ends in a NULL.
+ _locationCode.resize(locationCodeMaxSize);
+ _locationCode.back() = '\0';
+ }
+
+ _locationCodeSize = _locationCode.size();
+}
+
+size_t Callout::flattenedSize() const
{
size_t size = sizeof(_size) + sizeof(_flags) + sizeof(_priority) +
sizeof(_locationCodeSize) + _locationCodeSize;
diff --git a/extensions/openpower-pels/callout.hpp b/extensions/openpower-pels/callout.hpp
index caf3aec..c8bb0a3 100644
--- a/extensions/openpower-pels/callout.hpp
+++ b/extensions/openpower-pels/callout.hpp
@@ -3,6 +3,7 @@
#include "fru_identity.hpp"
#include "mru.hpp"
#include "pce_identity.hpp"
+#include "pel_types.hpp"
#include "stream.hpp"
namespace openpower
@@ -34,6 +35,19 @@
class Callout
{
public:
+ /**
+ * @brief Which callout substructures are included.
+ */
+ enum calloutFlags
+ {
+ calloutType = 0b0010'0000,
+ fruIdentIncluded = 0b0000'1000,
+ mruIncluded = 0b0000'0100
+
+ // Leaving out the various PCE identity ones since
+ // we don't use them.
+ };
+
Callout() = delete;
~Callout() = default;
Callout(const Callout&) = delete;
@@ -51,11 +65,38 @@
explicit Callout(Stream& pel);
/**
+ * @brief Constructor
+ *
+ * Creates the objects with a FRUIdentity substructure that calls
+ * out a normal hardware FRU.
+ *
+ * @param[in] priority - The priority of the callout
+ * @param[in] locationCode - The location code of the callout
+ * @param[in] partNumber - The part number of the callout
+ * @param[in] ccin - The CCIN of the callout
+ * @param[in] serialNumber - The serial number of the callout
+ */
+ Callout(CalloutPriority priority, const std::string& locationCode,
+ const std::string& partNumber, const std::string& ccin,
+ const std::string& serialNumber);
+
+ /**
+ * @brief Constructor
+ *
+ * Creates the objects with a FRUIdentity substructure that calls
+ * out maintenance procedure.
+ *
+ * @param[in] priority - The priority of the callout
+ * @param[in] procedure - The maintenance procedure
+ */
+ Callout(CalloutPriority priority, MaintProcedure procedure);
+
+ /**
* @brief Returns the size of this object when flattened into a PEL
*
* @return size_t - The size of the section
*/
- size_t flattenedSize();
+ size_t flattenedSize() const;
/**
* @brief Flatten the object into the stream
@@ -101,6 +142,16 @@
}
/**
+ * @brief Returns the location code size
+ *
+ * @return size_t - The size, including the terminating null.
+ */
+ size_t locationCodeSize() const
+ {
+ return _locationCodeSize;
+ }
+
+ /**
* @brief Returns the FRU identity substructure
*
* @return const std::unique_ptr<FRUIdentity>&
@@ -123,7 +174,7 @@
/**
* @brief Returns the MRU identity substructure
*
- * @return const std::unique_ptr<FRUIdentity>&
+ * @return const std::unique_ptr<MRU>&
*/
const std::unique_ptr<MRU>& mru() const
{
@@ -132,6 +183,13 @@
private:
/**
+ * @brief Sets the location code field
+ *
+ * @param[in] locationCode - The location code string
+ */
+ void setLocationCode(const std::string& locationCode);
+
+ /**
* @brief The size of this structure in the PEL
*/
uint8_t _size;
@@ -152,7 +210,7 @@
* Includes the NULL termination, and must be a
* multiple of 4 (padded with zeros)
*/
- uint8_t _locationCodeSize;
+ uint8_t _locationCodeSize = 0;
/**
* @brief NULL terminated location code