host-bmc: Process host TL PDR

Process host TL PDR and build TLPDRMap for easy lookup based on
PLDMTerminusHandle, the parsing of the host state sensors is done
after the TL PDR's are processed.

Tested:

Tested on Rainier simics and sensor event from host is handled
and the D-Bus object is updated.

Change-Id: I3b5903c4e6a071465ac84cedb9723019dc6d06fa
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/common/types.hpp b/common/types.hpp
index d701cfc..c2b3510 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -27,8 +27,9 @@
 namespace pdr

 {

 

+using EID = uint8_t;

 using TerminusHandle = uint16_t;

-using TerminusID = uint16_t;

+using TerminusID = uint8_t;

 using SensorID = uint16_t;

 using EntityType = uint16_t;

 using EntityInstance = uint16_t;

diff --git a/host-bmc/host_pdr_handler.cpp b/host-bmc/host_pdr_handler.cpp
index f8594d6..31065a4 100644
--- a/host-bmc/host_pdr_handler.cpp
+++ b/host-bmc/host_pdr_handler.cpp
@@ -106,6 +106,8 @@
                                     PLDM_GET_PDR_REQ_BYTES);
     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
     bool merged = false;
+    PDRList stateSensorPDRs{};
+    TLPDRMap tlpdrInfo{};
 
     uint32_t nextRecordHandle{};
     uint32_t recordHandle{};
@@ -189,16 +191,19 @@
                 }
                 else
                 {
-                    if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
+                    if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
                     {
-                        const auto& [terminusHandle, sensorID, sensorInfo] =
-                            responder::pdr_utils::parseStateSensorPDR(pdr);
-                        SensorEntry sensorEntry{};
-                        // TODO: Lookup Terminus ID from the Terminus Locator
-                        // PDR with terminusHandle
-                        sensorEntry.terminusID = 0;
-                        sensorEntry.sensorID = sensorID;
-                        sensorMap.emplace(sensorEntry, std::move(sensorInfo));
+                        auto tlpdr =
+                            reinterpret_cast<const pldm_terminus_locator_pdr*>(
+                                pdr.data());
+                        tlpdrInfo.emplace(
+                            static_cast<pdr::TerminusHandle>(
+                                tlpdr->terminus_handle),
+                            static_cast<pdr::TerminusID>(tlpdr->tid));
+                    }
+                    else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
+                    {
+                        stateSensorPDRs.emplace_back(pdr);
                     }
                     pldm_pdr_add(repo, pdr.data(), respCount, 0, true);
                 }
@@ -217,6 +222,8 @@
         }
     } while (recordHandle);
 
+    parseStateSensorPDRs(stateSensorPDRs, tlpdrInfo);
+
     if (merged)
     {
         // We have merged host's entity association PDRs with our own. Send an
@@ -371,4 +378,27 @@
     }
 }
 
+void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs,
+                                          const TLPDRMap& tlpdrInfo)
+{
+    for (const auto& pdr : stateSensorPDRs)
+    {
+        SensorEntry sensorEntry{};
+        const auto& [terminusHandle, sensorID, sensorInfo] =
+            responder::pdr_utils::parseStateSensorPDR(pdr);
+        sensorEntry.sensorID = sensorID;
+        try
+        {
+            sensorEntry.terminusID = tlpdrInfo.at(terminusHandle);
+        }
+        // If there is no mapping for terminusHandle assign the reserved TID
+        // value of 0xFF to indicate that.
+        catch (const std::out_of_range& e)
+        {
+            sensorEntry.terminusID = PLDM_TID_RESERVED;
+        }
+        sensorMap.emplace(sensorEntry, std::move(sensorInfo));
+    }
+}
+
 } // namespace pldm
diff --git a/host-bmc/host_pdr_handler.hpp b/host-bmc/host_pdr_handler.hpp
index fbb206c..9377cb6 100644
--- a/host-bmc/host_pdr_handler.hpp
+++ b/host-bmc/host_pdr_handler.hpp
@@ -51,6 +51,7 @@
 };
 
 using HostStateSensorMap = std::map<SensorEntry, pdr::SensorInfo>;
+using PDRList = std::vector<std::vector<uint8_t>>;
 
 /** @class HostPDRHandler
  *  @brief This class can fetch and process PDRs from host firmware
@@ -71,6 +72,8 @@
     HostPDRHandler& operator=(HostPDRHandler&&) = delete;
     ~HostPDRHandler() = default;
 
+    using TLPDRMap = std::map<pdr::TerminusHandle, pdr::TerminusID>;
+
     /** @brief Constructor
      *  @param[in] mctp_fd - fd of MCTP communications socket
      *  @param[in] mctp_eid - MCTP EID of host firmware
@@ -112,6 +115,16 @@
         return sensorMap.at(entry);
     }
 
+    /** @brief Parse state sensor PDRs and populate the sensorMap lookup data
+     *         structure
+     *
+     *  @param[in] stateSensorPDRs - host state sensor PDRs
+     *  @param[in] tlpdrInfo - terminus locator PDRs info
+     *
+     */
+    void parseStateSensorPDRs(const PDRList& stateSensorPDRs,
+                              const TLPDRMap& tlpdrInfo);
+
   private:
     /** @brief fetchPDR schedules work on the event loop, this method does the
      *  actual work. This is so that the PDR exchg with the host is async.
diff --git a/libpldm/platform.h b/libpldm/platform.h
index 91128b7..7834f59 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -49,6 +49,7 @@
 #define PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH 2
 
 #define PLDM_INVALID_EFFECTER_ID 0xFFFF
+#define PLDM_TID_RESERVED 0xFF
 
 enum pldm_effecter_data_size {
 	PLDM_EFFECTER_DATA_SIZE_UINT8,