PEL: Create FRUIdentity with FRUs/procedures
Add constructors to the FRUIdentity structure in the SRC section to take
either a hardware callout with PN/SN/CCIN, or a maintenance procedure
callout with a maintenance procedure enum. Both of these also take
callout priority.
These will be used when creating PELs that have callouts.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I5071d98df38b63ba53224c3f3b853e57234ed74e
diff --git a/extensions/openpower-pels/fru_identity.cpp b/extensions/openpower-pels/fru_identity.cpp
index 73b4200..7e9bf1b 100644
--- a/extensions/openpower-pels/fru_identity.cpp
+++ b/extensions/openpower-pels/fru_identity.cpp
@@ -15,6 +15,8 @@
*/
#include "fru_identity.hpp"
+#include "pel_values.hpp"
+
namespace openpower
{
namespace pels
@@ -26,17 +28,17 @@
{
pel >> _type >> _size >> _flags;
- if (_flags & (pnSupplied | maintProcSupplied))
+ if (hasPN() || hasMP())
{
pel.read(_pnOrProcedureID.data(), _pnOrProcedureID.size());
}
- if (_flags & ccinSupplied)
+ if (hasCCIN())
{
pel.read(_ccin.data(), _ccin.size());
}
- if (_flags & snSupplied)
+ if (hasSN())
{
pel.read(_sn.data(), _sn.size());
}
@@ -64,6 +66,29 @@
return size;
}
+FRUIdentity::FRUIdentity(const std::string& partNumber, const std::string& ccin,
+ const std::string& serialNumber)
+{
+ _type = substructureType;
+ _flags = hardwareFRU;
+
+ setPartNumber(partNumber);
+ setCCIN(ccin);
+ setSerialNumber(serialNumber);
+
+ _size = flattenedSize();
+}
+
+FRUIdentity::FRUIdentity(MaintProcedure procedure)
+{
+ _type = substructureType;
+ _flags = maintenanceProc;
+
+ setMaintenanceProcedure(procedure);
+
+ _size = flattenedSize();
+}
+
std::optional<std::string> FRUIdentity::getPN() const
{
if (hasPN())
@@ -93,6 +118,12 @@
if (hasCCIN())
{
std::string ccin{_ccin.begin(), _ccin.begin() + _ccin.size()};
+
+ // Don't leave any NULLs in the string (not there usually)
+ if (auto pos = ccin.find('\0'); pos != std::string::npos)
+ {
+ ccin.resize(pos);
+ }
return ccin;
}
@@ -104,6 +135,12 @@
if (hasSN())
{
std::string sn{_sn.begin(), _sn.begin() + _sn.size()};
+
+ // Don't leave any NULLs in the string (not there usually)
+ if (auto pos = sn.find('\0'); pos != std::string::npos)
+ {
+ sn.resize(pos);
+ }
return sn;
}
@@ -130,6 +167,56 @@
}
}
+void FRUIdentity::setPartNumber(const std::string& partNumber)
+{
+ _flags |= pnSupplied;
+ _flags &= ~maintProcSupplied;
+
+ auto pn = partNumber;
+
+ // Strip leading whitespace on this one.
+ while (' ' == pn.front())
+ {
+ pn = pn.substr(1);
+ }
+
+ // Note: strncpy only writes NULLs if pn short
+ strncpy(_pnOrProcedureID.data(), pn.c_str(), _pnOrProcedureID.size());
+
+ // ensure null terminated
+ _pnOrProcedureID.back() = 0;
+}
+
+void FRUIdentity::setCCIN(const std::string& ccin)
+{
+ _flags |= ccinSupplied;
+
+ // Note: _ccin not null terminated, though strncpy writes NULLs if short
+ strncpy(_ccin.data(), ccin.c_str(), _ccin.size());
+}
+
+void FRUIdentity::setSerialNumber(const std::string& serialNumber)
+{
+ _flags |= snSupplied;
+
+ // Note: _sn not null terminated, though strncpy writes NULLs if short
+ strncpy(_sn.data(), serialNumber.c_str(), _sn.size());
+}
+
+void FRUIdentity::setMaintenanceProcedure(MaintProcedure procedure)
+{
+ _flags |= maintProcSupplied;
+ _flags &= ~pnSupplied;
+
+ auto proc = pel_values::getMaintProcedure(procedure);
+
+ strncpy(_pnOrProcedureID.data(), std::get<pel_values::mpNamePos>(*proc),
+ _pnOrProcedureID.size());
+
+ // ensure null terminated
+ _pnOrProcedureID.back() = 0;
+}
+
} // namespace src
} // namespace pels
} // namespace openpower
diff --git a/extensions/openpower-pels/fru_identity.hpp b/extensions/openpower-pels/fru_identity.hpp
index bf7b2f7..016f3fd 100644
--- a/extensions/openpower-pels/fru_identity.hpp
+++ b/extensions/openpower-pels/fru_identity.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "pel_types.hpp"
#include "stream.hpp"
#include <optional>
@@ -71,6 +72,28 @@
explicit FRUIdentity(Stream& pel);
/**
+ * Constructor
+ *
+ * Creates the object as a hardware callout with the part number,
+ * CCIN, and serial number fields supplied.
+ *
+ * @param[in] partNumber - The part number of the FRU
+ * @param[in] ccin - The CCIN of the FRU
+ * @param[in] serialNumber - The serial number of the FRU
+ */
+ FRUIdentity(const std::string& partNumber, const std::string& ccin,
+ const std::string& serialNumber);
+
+ /**
+ * @brief Constructor
+ *
+ * Creates the object with a maintenance procedure callout.
+ *
+ * @param[in] procedure - The procedure to use
+ */
+ FRUIdentity(MaintProcedure procedure);
+
+ /**
* @brief Flatten the object into the stream
*
* @param[in] stream - The stream to write to
@@ -85,6 +108,15 @@
size_t flattenedSize() const;
/**
+ * @brief Returns the type field
+ *
+ * @return uint16_t - The type, always 0x4944 "ID".
+ */
+ uint16_t type() const
+ {
+ return _type;
+ }
+ /**
* @brief The failing component type for this FRU callout.
*
* @return FailingComponentType
@@ -173,6 +205,35 @@
}
/**
+ * @brief Sets the 8 character null terminated part
+ * number field to the string passed in.
+ *
+ * @param[in] partNumber - The part number string.
+ */
+ void setPartNumber(const std::string& partNumber);
+
+ /**
+ * @brief Sets the 4 character CCIN field.
+ *
+ * @param[in] ccin - The CCIN string
+ */
+ void setCCIN(const std::string& ccin);
+
+ /**
+ * @brief Sets the 12 character serial number field.
+ *
+ * @param[in] serialNumber - The serial number string
+ */
+ void setSerialNumber(const std::string& serialNumber);
+
+ /**
+ * @brief Sets the 8 character null terminated procedure
+ * field. This is in the same field as the part
+ * number since they are mutually exclusive.
+ */
+ void setMaintenanceProcedure(MaintProcedure procedure);
+
+ /**
* @brief The callout substructure type field. Will be "ID".
*/
uint16_t _type;
diff --git a/extensions/openpower-pels/pel_types.hpp b/extensions/openpower-pels/pel_types.hpp
index d23ebe8..f6f66a5 100644
--- a/extensions/openpower-pels/pel_types.hpp
+++ b/extensions/openpower-pels/pel_types.hpp
@@ -131,6 +131,19 @@
};
/**
+ * @brief Callout priority values
+ */
+enum class CalloutPriority
+{
+ high = 'H',
+ medium = 'M',
+ mediumGroupA = 'A',
+ mediumGroupB = 'B',
+ mediumGroupC = 'C',
+ low = 'L'
+};
+
+/**
* @brief Maintenance procedure enums
*/
enum class MaintProcedure