Move resolution callout support to service data class

The resolution callout support is only accessible for service actions
defined by the RAS data files. Unfortunately, this does not work for any
plugins that need to make callouts as well. Therefore, the callout logic
was moved to a common location that is accessible by the different
classes.

Change-Id: I5679c3b2e44bb039227740975cdef03c94747b3b
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/analyzer/resolution.cpp b/analyzer/resolution.cpp
index ac5410e..f9c09b5 100644
--- a/analyzer/resolution.cpp
+++ b/analyzer/resolution.cpp
@@ -45,64 +45,13 @@
 
 //------------------------------------------------------------------------------
 
-void __calloutTarget(ServiceData& io_sd, pdbg_target* i_target,
-                     const callout::Priority& i_priority, bool i_guard)
-{
-    nlohmann::json callout;
-    callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
-    callout["Priority"]     = i_priority.getUserDataString();
-    callout["Deconfigured"] = false;
-    callout["Guarded"]      = false; // default
-
-    // Check if guard info should be added.
-    if (i_guard)
-    {
-        auto guardType = io_sd.queryGuardPolicy();
-
-        if (!(callout::GuardType::NONE == guardType))
-        {
-            callout["Guarded"]    = true;
-            callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
-            callout["GuardType"]  = guardType.getString();
-        }
-    }
-
-    io_sd.addCallout(callout);
-}
-
-//------------------------------------------------------------------------------
-
-void __calloutBackplane(ServiceData& io_sd, const callout::Priority& i_priority)
-{
-    // TODO: There isn't a device tree object for this. So will need to hardcode
-    //       the location code for now. In the future, we will need a mechanism
-    //       to make this data driven.
-
-    nlohmann::json callout;
-    callout["LocationCode"] = "P0";
-    callout["Priority"]     = i_priority.getUserDataString();
-    callout["Deconfigured"] = false;
-    callout["Guarded"]      = false;
-    io_sd.addCallout(callout);
-}
-
-//------------------------------------------------------------------------------
-
 void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
 {
     // Get the target for the hardware callout.
     auto target = __getUnitTarget(__getRootCauseChipTarget(io_sd), iv_unitPath);
 
-    // Add the actual callout to the service data.
-    __calloutTarget(io_sd, target, iv_priority, iv_guard);
-
-    // Add the callout FFDC to the service data.
-    nlohmann::json ffdc;
-    ffdc["Callout Type"] = "Hardware Callout";
-    ffdc["Target"]       = util::pdbg::getPhysDevPath(target);
-    ffdc["Priority"]     = iv_priority.getRegistryString();
-    ffdc["Guard"]        = iv_guard;
-    io_sd.addCalloutFFDC(ffdc);
+    // Add the callout and the FFDC to the service data.
+    io_sd.calloutTarget(target, iv_priority, iv_guard);
 }
 
 //------------------------------------------------------------------------------
@@ -115,20 +64,8 @@
     // Get the endpoint target for the receiving side of the bus.
     auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
 
-    // Get the endpoint target for the transfer side of the bus.
-    auto txTarget = util::pdbg::getConnectedTarget(rxTarget, iv_busType);
-
-    // Callout the TX endpoint.
-    __calloutTarget(io_sd, txTarget, iv_priority, iv_guard);
-
-    // Add the callout FFDC to the service data.
-    nlohmann::json ffdc;
-    ffdc["Callout Type"] = "Connected Callout";
-    ffdc["Bus Type"]     = iv_busType.getString();
-    ffdc["Target"]       = util::pdbg::getPhysDevPath(txTarget);
-    ffdc["Priority"]     = iv_priority.getRegistryString();
-    ffdc["Guard"]        = iv_guard;
-    io_sd.addCalloutFFDC(ffdc);
+    // Add the callout and the FFDC to the service data.
+    io_sd.calloutConnected(rxTarget, iv_busType, iv_priority, iv_guard);
 }
 
 //------------------------------------------------------------------------------
@@ -141,65 +78,24 @@
     // Get the endpoint target for the receiving side of the bus.
     auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
 
-    // Get the endpoint target for the transfer side of the bus.
-    auto txTarget = util::pdbg::getConnectedTarget(rxTarget, iv_busType);
-
-    // Callout the RX endpoint.
-    __calloutTarget(io_sd, rxTarget, iv_priority, iv_guard);
-
-    // Callout the TX endpoint.
-    __calloutTarget(io_sd, txTarget, iv_priority, iv_guard);
-
-    // Callout everything else in between.
-    // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
-    __calloutBackplane(io_sd, iv_priority);
-
-    // Add the callout FFDC to the service data.
-    nlohmann::json ffdc;
-    ffdc["Callout Type"] = "Bus Callout";
-    ffdc["Bus Type"]     = iv_busType.getString();
-    ffdc["RX Target"]    = util::pdbg::getPhysDevPath(rxTarget);
-    ffdc["TX Target"]    = util::pdbg::getPhysDevPath(txTarget);
-    ffdc["Priority"]     = iv_priority.getRegistryString();
-    ffdc["Guard"]        = iv_guard;
-    io_sd.addCalloutFFDC(ffdc);
+    // Add the callout and the FFDC to the service data.
+    io_sd.calloutBus(rxTarget, iv_busType, iv_priority, iv_guard);
 }
 
 //------------------------------------------------------------------------------
 
 void ClockCalloutResolution::resolve(ServiceData& io_sd) const
 {
-    // Callout the clock target.
-    // TODO: For P10, the callout is simply the backplane. Also, there are no
-    //       clock targets in the device tree. So at the moment there is no
-    //       guard support for clock targets.
-    __calloutBackplane(io_sd, iv_priority);
-
-    // Add the callout FFDC to the service data.
-    // TODO: Add the target and guard type if guard is ever supported.
-    nlohmann::json ffdc;
-    ffdc["Callout Type"] = "Clock Callout";
-    ffdc["Clock Type"]   = iv_clockType.getString();
-    ffdc["Priority"]     = iv_priority.getRegistryString();
-    io_sd.addCalloutFFDC(ffdc);
+    // Add the callout and the FFDC to the service data.
+    io_sd.calloutClock(iv_clockType, iv_priority, iv_guard);
 }
 
 //------------------------------------------------------------------------------
 
 void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
 {
-    // Add the actual callout to the service data.
-    nlohmann::json callout;
-    callout["Procedure"] = iv_procedure.getString();
-    callout["Priority"]  = iv_priority.getUserDataString();
-    io_sd.addCallout(callout);
-
-    // Add the callout FFDC to the service data.
-    nlohmann::json ffdc;
-    ffdc["Callout Type"] = "Procedure Callout";
-    ffdc["Procedure"]    = iv_procedure.getString();
-    ffdc["Priority"]     = iv_priority.getRegistryString();
-    io_sd.addCalloutFFDC(ffdc);
+    // Add the callout and the FFDC to the service data.
+    io_sd.calloutProcedure(iv_procedure, iv_priority);
 }
 
 //------------------------------------------------------------------------------
diff --git a/analyzer/service_data.cpp b/analyzer/service_data.cpp
index c569739..e544b6e 100644
--- a/analyzer/service_data.cpp
+++ b/analyzer/service_data.cpp
@@ -3,6 +3,119 @@
 namespace analyzer
 {
 
+//------------------------------------------------------------------------------
+
+void ServiceData::calloutTarget(pdbg_target* i_target,
+                                const callout::Priority& i_priority,
+                                bool i_guard)
+{
+    // Add the target to the callout list.
+    addTargetCallout(i_target, i_priority, i_guard);
+
+    // Add the callout FFDC.
+    nlohmann::json ffdc;
+    ffdc["Callout Type"] = "Hardware Callout";
+    ffdc["Target"]       = util::pdbg::getPhysDevPath(i_target);
+    ffdc["Priority"]     = i_priority.getRegistryString();
+    ffdc["Guard"]        = i_guard;
+    addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceData::calloutConnected(pdbg_target* i_rxTarget,
+                                   const callout::BusType& i_busType,
+                                   const callout::Priority& i_priority,
+                                   bool i_guard)
+{
+    // Get the endpoint target for the transfer side of the bus.
+    auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
+
+    // Callout the TX endpoint.
+    addTargetCallout(txTarget, i_priority, i_guard);
+
+    // Add the callout FFDC.
+    nlohmann::json ffdc;
+    ffdc["Callout Type"] = "Connected Callout";
+    ffdc["Bus Type"]     = i_busType.getString();
+    ffdc["RX Target"]    = util::pdbg::getPhysDevPath(i_rxTarget);
+    ffdc["TX Target"]    = util::pdbg::getPhysDevPath(txTarget);
+    ffdc["Priority"]     = i_priority.getRegistryString();
+    ffdc["Guard"]        = i_guard;
+    addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceData::calloutBus(pdbg_target* i_rxTarget,
+                             const callout::BusType& i_busType,
+                             const callout::Priority& i_priority, bool i_guard)
+{
+    // Get the endpoint target for the transfer side of the bus.
+    auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
+
+    // Callout the RX endpoint.
+    addTargetCallout(i_rxTarget, i_priority, i_guard);
+
+    // Callout the TX endpoint.
+    addTargetCallout(txTarget, i_priority, i_guard);
+
+    // Callout everything else in between.
+    // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
+    addBackplaneCallout(i_priority);
+
+    // Add the callout FFDC.
+    nlohmann::json ffdc;
+    ffdc["Callout Type"] = "Bus Callout";
+    ffdc["Bus Type"]     = i_busType.getString();
+    ffdc["RX Target"]    = util::pdbg::getPhysDevPath(i_rxTarget);
+    ffdc["TX Target"]    = util::pdbg::getPhysDevPath(txTarget);
+    ffdc["Priority"]     = i_priority.getRegistryString();
+    ffdc["Guard"]        = i_guard;
+    addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceData::calloutClock(const callout::ClockType& i_clockType,
+                               const callout::Priority& i_priority, bool)
+{
+    // Callout the clock target.
+    // TODO: For P10, the callout is simply the backplane. Also, there are no
+    //       clock targets in the device tree. So at the moment there is no
+    //       guard support for clock targets.
+    addBackplaneCallout(i_priority);
+
+    // Add the callout FFDC.
+    // TODO: Add the target and guard type if guard is ever supported.
+    nlohmann::json ffdc;
+    ffdc["Callout Type"] = "Clock Callout";
+    ffdc["Clock Type"]   = i_clockType.getString();
+    ffdc["Priority"]     = i_priority.getRegistryString();
+    addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceData::calloutProcedure(const callout::Procedure& i_procedure,
+                                   const callout::Priority& i_priority)
+{
+    // Add the actual callout to the service data.
+    nlohmann::json callout;
+    callout["Procedure"] = i_procedure.getString();
+    callout["Priority"]  = i_priority.getUserDataString();
+    addCallout(callout);
+
+    // Add the callout FFDC.
+    nlohmann::json ffdc;
+    ffdc["Callout Type"] = "Procedure Callout";
+    ffdc["Procedure"]    = i_procedure.getString();
+    ffdc["Priority"]     = i_priority.getRegistryString();
+    addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
 void ServiceData::addCallout(const nlohmann::json& i_callout)
 {
     // The new callout is either a hardware callout with a location code or a
@@ -51,4 +164,53 @@
     }
 }
 
+//------------------------------------------------------------------------------
+
+void ServiceData::addTargetCallout(pdbg_target* i_target,
+                                   const callout::Priority& i_priority,
+                                   bool i_guard)
+{
+    nlohmann::json callout;
+
+    callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
+    callout["Priority"]     = i_priority.getUserDataString();
+    callout["Deconfigured"] = false;
+    callout["Guarded"]      = false; // default
+
+    // Check if guard info should be added.
+    if (i_guard)
+    {
+        auto guardType = queryGuardPolicy();
+
+        if (!(callout::GuardType::NONE == guardType))
+        {
+            callout["Guarded"]    = true;
+            callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
+            callout["GuardType"]  = guardType.getString();
+        }
+    }
+
+    addCallout(callout);
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceData::addBackplaneCallout(const callout::Priority& i_priority)
+{
+    // TODO: There isn't a device tree object for this. So will need to hardcode
+    //       the location code for now. In the future, we will need a mechanism
+    //       to make this data driven.
+
+    nlohmann::json callout;
+
+    callout["LocationCode"] = "P0";
+    callout["Priority"]     = i_priority.getUserDataString();
+    callout["Deconfigured"] = false;
+    callout["Guarded"]      = false;
+
+    addCallout(callout);
+}
+
+//------------------------------------------------------------------------------
+
 } // namespace analyzer
diff --git a/analyzer/service_data.hpp b/analyzer/service_data.hpp
index 0f9cac5..7e39589 100644
--- a/analyzer/service_data.hpp
+++ b/analyzer/service_data.hpp
@@ -4,6 +4,7 @@
 #include <analyzer/callout.hpp>
 #include <hei_main.hpp>
 #include <nlohmann/json.hpp>
+#include <util/pdbg.hpp>
 
 namespace analyzer
 {
@@ -78,6 +79,66 @@
     }
 
     /**
+     * @brief Add callout for a pdbg_target.
+     * @param i_target   The chip or unit target to add to the callout list.
+     * @param i_priority The callout priority.
+     * @param i_guard    True if guard is required. False, otherwise.
+     */
+    void calloutTarget(pdbg_target* i_target,
+                       const callout::Priority& i_priority, bool i_guard);
+
+    /**
+     * @brief Add callout for a connected target on the other side of a bus.
+     * @param i_rxTarget The target on the receiving side (RX) of the bus.
+     * @param i_busType  The bus type.
+     * @param i_priority The callout priority.
+     * @param i_guard    True if guard is required. False, otherwise.
+     */
+    void calloutConnected(pdbg_target* i_rxTarget,
+                          const callout::BusType& i_busType,
+                          const callout::Priority& i_priority, bool i_guard);
+
+    /**
+     * @brief Add callout for an entire bus.
+     * @param i_rxTarget The target on the receiving side (RX) of the bus.
+     * @param i_busType  The bus type.
+     * @param i_priority The callout priority.
+     * @param i_guard    True if guard is required. False, otherwise.
+     */
+    void calloutBus(pdbg_target* i_rxTarget, const callout::BusType& i_busType,
+                    const callout::Priority& i_priority, bool i_guard);
+
+    /**
+     * @brief Add callout for a clock.
+     * @param i_clockType The clock type.
+     * @param i_priority  The callout priority.
+     * @param i_guard     True if guard is required. False, otherwise.
+     */
+    void calloutClock(const callout::ClockType& i_clockType,
+                      const callout::Priority& i_priority, bool i_guard);
+
+    /**
+     * @brief Add callout for a service procedure.
+     * @param i_procedure The procedure type.
+     * @param i_priority  The callout priority.
+     */
+    void calloutProcedure(const callout::Procedure& i_procedure,
+                          const callout::Priority& i_priority);
+
+    /** @brief Accessor to iv_calloutList. */
+    const nlohmann::json& getCalloutList() const
+    {
+        return iv_calloutList;
+    }
+
+    /** @brief Accessor to iv_calloutFFDC. */
+    const nlohmann::json& getCalloutFFDC() const
+    {
+        return iv_calloutFFDC;
+    }
+
+  private:
+    /**
      * @brief Add callout information to the callout list.
      * @param The JSON object for this callout.
      */
@@ -93,17 +154,22 @@
         iv_calloutFFDC.push_back(i_ffdc);
     }
 
-    /** @brief Accessor to iv_calloutList. */
-    const nlohmann::json& getCalloutList() const
-    {
-        return iv_calloutList;
-    }
+    /**
+     * @brief A simple helper function for all the callout functions that need
+     *        to callout a target (callout only, no FFDC).
+     * @param i_target   The chip or unit target to add to the callout list.
+     * @param i_priority The callout priority.
+     * @param i_guard    True if guard is required. False, otherwise.
+     */
+    void addTargetCallout(pdbg_target* i_target,
+                          const callout::Priority& i_priority, bool i_guard);
 
-    /** @brief Accessor to iv_calloutFFDC. */
-    const nlohmann::json& getCalloutFFDC() const
-    {
-        return iv_calloutFFDC;
-    }
+    /**
+     * @brief A simple helper function for all the callout functions that need
+     *        to callout a the backplane (callout only, no FFDC).
+     * @param i_priority The callout priority.
+     */
+    void addBackplaneCallout(const callout::Priority& i_priority);
 };
 
 } // namespace analyzer
diff --git a/test/resolution_test.cpp b/test/resolution_test.cpp
index 8e43138..c894d01 100644
--- a/test/resolution_test.cpp
+++ b/test/resolution_test.cpp
@@ -235,21 +235,24 @@
         "Callout Type": "Connected Callout",
         "Guard": true,
         "Priority": "medium_group_A",
-        "Target": "/proc0/pib/perv24/pauc0/iohs0/smpgroup0"
+        "RX Target": "/proc0/pib/perv24/pauc0/iohs0/smpgroup0",
+        "TX Target": "/proc0/pib/perv24/pauc0/iohs0/smpgroup0"
     },
     {
         "Bus Type": "OMI_BUS",
         "Callout Type": "Connected Callout",
         "Guard": true,
         "Priority": "medium_group_B",
-        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
+        "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
+        "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
     },
     {
         "Bus Type": "OMI_BUS",
         "Callout Type": "Connected Callout",
         "Guard": true,
         "Priority": "medium_group_C",
-        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
+        "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
+        "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
     }
 ])";
     EXPECT_EQ(s, j.dump(4));
@@ -321,7 +324,8 @@
         "Callout Type": "Connected Callout",
         "Guard": true,
         "Priority": "medium_group_A",
-        "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
+        "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
+        "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
     },
     {
         "Bus Type": "OMI_BUS",