PEL: Let Callouts class have a Callout added

Add an addCallout() function to the Callouts class to add a new Callout
object to it.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ib2a352b3b10e2948c4e847d29a456b8de9cb3559
diff --git a/extensions/openpower-pels/callouts.cpp b/extensions/openpower-pels/callouts.cpp
index 17f5bdd..2440621 100644
--- a/extensions/openpower-pels/callouts.cpp
+++ b/extensions/openpower-pels/callouts.cpp
@@ -15,6 +15,8 @@
  */
 #include "callouts.hpp"
 
+#include <phosphor-logging/log.hpp>
+
 namespace openpower
 {
 namespace pels
@@ -46,6 +48,20 @@
     }
 }
 
+void Callouts::addCallout(std::unique_ptr<Callout> callout)
+{
+    if (_callouts.size() < maxNumberOfCallouts)
+    {
+        _callouts.push_back(std::move(callout));
+
+        _subsectionWordLength += _callouts.back()->flattenedSize() / 4;
+    }
+    else
+    {
+        using namespace phosphor::logging;
+        log<level::INFO>("Dropping PEL callout because at max");
+    }
+}
 } // namespace src
 } // namespace pels
 } // namespace openpower
diff --git a/extensions/openpower-pels/callouts.hpp b/extensions/openpower-pels/callouts.hpp
index 9226a1b..4a05306 100644
--- a/extensions/openpower-pels/callouts.hpp
+++ b/extensions/openpower-pels/callouts.hpp
@@ -10,6 +10,9 @@
 namespace src
 {
 
+constexpr uint8_t calloutsSubsectionID = 0xC0;
+constexpr size_t maxNumberOfCallouts = 10;
+
 /**
  * @class Callouts
  *
@@ -23,7 +26,6 @@
 class Callouts
 {
   public:
-    Callouts() = default;
     ~Callouts() = default;
     Callouts(const Callouts&) = delete;
     Callouts& operator=(const Callouts&) = delete;
@@ -33,6 +35,17 @@
     /**
      * @brief Constructor
      *
+     * Creates the object with no callouts.
+     */
+    Callouts() :
+        _subsectionID(calloutsSubsectionID), _subsectionFlags(0),
+        _subsectionWordLength(1)
+    {
+    }
+
+    /**
+     * @brief Constructor
+     *
      * Fills in this class's data fields from the stream.
      *
      * @param[in] pel - the PEL data stream
@@ -66,6 +79,13 @@
         return _callouts;
     }
 
+    /**
+     * @brief Adds a callout
+     *
+     * @param[in] callout - The callout to add
+     */
+    void addCallout(std::unique_ptr<Callout> callout);
+
   private:
     /**
      * @brief The ID of this subsection, which is 0xC0.
diff --git a/test/openpower-pels/src_callouts_test.cpp b/test/openpower-pels/src_callouts_test.cpp
index f192c15..b1fe9c4 100644
--- a/test/openpower-pels/src_callouts_test.cpp
+++ b/test/openpower-pels/src_callouts_test.cpp
@@ -89,3 +89,34 @@
 
     EXPECT_THROW(Callouts callouts{stream}, std::out_of_range);
 }
+
+TEST(CalloutsTest, TestAddCallouts)
+{
+    Callouts callouts;
+
+    // Empty Callouts size
+    size_t lastSize = 4;
+
+    for (size_t i = 0; i < maxNumberOfCallouts; i++)
+    {
+        auto callout = std::make_unique<Callout>(
+            CalloutPriority::high, "U1-P1", "1234567", "ABCD", "123456789ABC");
+        auto calloutSize = callout->flattenedSize();
+
+        callouts.addCallout(std::move(callout));
+
+        EXPECT_EQ(callouts.flattenedSize(), lastSize + calloutSize);
+
+        lastSize = callouts.flattenedSize();
+
+        EXPECT_EQ(callouts.callouts().size(), i + 1);
+    }
+
+    // Try to add an 11th callout.  Shouldn't work
+
+    auto callout = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
+                                             "1234567", "ABCD", "123456789ABC");
+    callouts.addCallout(std::move(callout));
+
+    EXPECT_EQ(callouts.callouts().size(), maxNumberOfCallouts);
+}