mctp-discovery: Get endpoint UUID from D-Bus

Getting the MCTP endpoint UUID from `UUID` D-Bus property in
`xyz.openbmc_project.Common.UUID` D-Bus interface of MCTP Endpoint
object. Update the endpoint MCTPInfo with that UUID.

Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: I35e83eac11fafafdad57cdc0285b344650caefbd
diff --git a/common/types.hpp b/common/types.hpp
index e3b10ee..86b7542 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -19,6 +19,7 @@
 using UUID = std::string;
 using Request = std::vector<uint8_t>;
 using Response = std::vector<uint8_t>;
+using MCTPMsgTypes = std::vector<uint8_t>;
 using Command = uint8_t;
 
 /** @brief MCTP Endpoint Medium type in string
@@ -40,6 +41,16 @@
  */
 using MctpInfo = std::tuple<eid, UUID, MctpMedium, NetworkId>;
 
+/** @brief Type definition of MCTP endpoint D-Bus properties in
+ *         xyz.openbmc_project.MCTP.Endpoint D-Bus interface.
+ *
+ *         NetworkId: MCTP network index
+ *         eid : Endpoint EID in byte. Defined to match with MCTP D-Bus
+ *               interface
+ *         MCTPMsgTypes: MCTP message types
+ */
+using MctpEndpointProps = std::tuple<NetworkId, eid, MCTPMsgTypes>;
+
 /** @brief Type defined for list of MCTP interface information
  */
 using MctpInfos = std::vector<MctpInfo>;
diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp
index d0122c9..1b6cd30 100644
--- a/requester/mctp_endpoint_discovery.cpp
+++ b/requester/mctp_endpoint_discovery.cpp
@@ -5,6 +5,8 @@
 #include "common/types.hpp"
 #include "common/utils.hpp"
 
+#include <linux/mctp.h>
+
 #include <phosphor-logging/lg2.hpp>
 
 #include <algorithm>
@@ -58,43 +60,74 @@
         for (const auto& serviceIter : services)
         {
             const std::string& service = serviceIter.first;
-            try
+            const MctpEndpointProps& epProps =
+                getMctpEndpointProps(service, path);
+            const UUID& uuid = getEndpointUUIDProp(service, path);
+            auto types = std::get<MCTPMsgTypes>(epProps);
+            if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
+                types.end())
             {
-                auto properties =
-                    pldm::utils::DBusHandler().getDbusPropertiesVariant(
-                        service.c_str(), path.c_str(), MCTPInterface);
-
-                if (properties.contains("NetworkId") &&
-                    properties.contains("EID") &&
-                    properties.contains("SupportedMessageTypes"))
-                {
-                    auto networkId =
-                        std::get<NetworkId>(properties.at("NetworkId"));
-                    auto eid = std::get<mctp_eid_t>(properties.at("EID"));
-                    auto types = std::get<std::vector<uint8_t>>(
-                        properties.at("SupportedMessageTypes"));
-                    if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
-                        types.end())
-                    {
-                        info(
-                            "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
-                            "NETWORK", networkId, "EID", eid);
-                        mctpInfos.emplace_back(
-                            MctpInfo(eid, emptyUUID, "", networkId));
-                    }
-                }
-            }
-            catch (const sdbusplus::exception_t& e)
-            {
-                error(
-                    "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
-                    "ERROR", e, "SERVICE", service, "PATH", path);
-                return;
+                mctpInfos.emplace_back(
+                    MctpInfo(std::get<eid>(epProps), uuid, "",
+                             std::get<NetworkId>(epProps)));
             }
         }
     }
 }
 
+MctpEndpointProps MctpDiscovery::getMctpEndpointProps(
+    const std::string& service, const std::string& path)
+{
+    try
+    {
+        auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant(
+            service.c_str(), path.c_str(), MCTPInterface);
+
+        if (properties.contains("NetworkId") && properties.contains("EID") &&
+            properties.contains("SupportedMessageTypes"))
+        {
+            auto networkId = std::get<NetworkId>(properties.at("NetworkId"));
+            auto eid = std::get<mctp_eid_t>(properties.at("EID"));
+            auto types = std::get<std::vector<uint8_t>>(
+                properties.at("SupportedMessageTypes"));
+            return MctpEndpointProps(networkId, eid, types);
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        error(
+            "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
+            "SERVICE", service, "PATH", path, "ERROR", e);
+        return MctpEndpointProps(0, MCTP_ADDR_ANY, {});
+    }
+
+    return MctpEndpointProps(0, MCTP_ADDR_ANY, {});
+}
+
+UUID MctpDiscovery::getEndpointUUIDProp(const std::string& service,
+                                        const std::string& path)
+{
+    try
+    {
+        auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant(
+            service.c_str(), path.c_str(), EndpointUUID);
+
+        if (properties.contains("UUID"))
+        {
+            return std::get<UUID>(properties.at("UUID"));
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        error(
+            "Error reading Endpoint UUID property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
+            "SERVICE", service, "PATH", path, "ERROR", e);
+        return static_cast<UUID>(emptyUUID);
+    }
+
+    return static_cast<UUID>(emptyUUID);
+}
+
 void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
                                       MctpInfos& mctpInfos)
 {
@@ -103,6 +136,7 @@
     using Property = std::string;
     using PropertyMap = std::map<Property, dbus::Value>;
     std::map<std::string, PropertyMap> interfaces;
+    std::string uuid = emptyUUID;
 
     try
     {
@@ -116,6 +150,19 @@
         return;
     }
 
+    /* Get UUID */
+    try
+    {
+        auto service = pldm::utils::DBusHandler().getService(
+            objPath.str.c_str(), EndpointUUID);
+        uuid = getEndpointUUIDProp(service, objPath.str);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        error("Error getting Endpoint UUID D-Bus interface, error - {ERROR}",
+              "ERROR", e);
+    }
+
     for (const auto& [intfName, properties] : interfaces)
     {
         if (intfName == MCTPInterface)
@@ -133,10 +180,9 @@
                     types.end())
                 {
                     info(
-                        "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
-                        "NETWORK", networkId, "EID", eid);
-                    mctpInfos.emplace_back(
-                        MctpInfo(eid, emptyUUID, "", networkId));
+                        "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' UUID '{UUID}'",
+                        "NETWORK", networkId, "EID", eid, "UUID", uuid);
+                    mctpInfos.emplace_back(MctpInfo(eid, uuid, "", networkId));
                 }
             }
         }
diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp
index 643d1ce..1bd9526 100644
--- a/requester/mctp_endpoint_discovery.hpp
+++ b/requester/mctp_endpoint_discovery.hpp
@@ -17,6 +17,7 @@
 const std::string emptyUUID = "00000000-0000-0000-0000-000000000000";
 constexpr const char* MCTPService = "xyz.openbmc_project.MCTP";
 constexpr const char* MCTPInterface = "xyz.openbmc_project.MCTP.Endpoint";
+constexpr const char* EndpointUUID = "xyz.openbmc_project.Common.UUID";
 constexpr const char* MCTPPath = "/xyz/openbmc_project/mctp";
 
 /** @class MctpDiscoveryHandlerIntf
@@ -124,6 +125,28 @@
                                      MctpInfos& removedInfos);
 
   private:
+    /** @brief Get MCTP Endpoint D-Bus Properties in the
+     *         `xyz.openbmc_project.MCTP.Endpoint` D-Bus interface
+     *
+     *  @param[in] service - the MCTP service name
+     *  @param[in] path - the MCTP endpoints object path
+     *
+     *  @return tuple of Network Index, Endpoint ID and MCTP message types
+     */
+    MctpEndpointProps getMctpEndpointProps(const std::string& service,
+                                           const std::string& path);
+
+    /** @brief Get Endpoint UUID from `UUID` D-Bus property in the
+     *         `xyz.openbmc_project.Common.UUID` D-Bus interface.
+     *
+     *  @param[in] service - the MCTP service name
+     *  @param[in] path - the MCTP endpoints object path
+     *
+     *  @return Endpoint UUID
+     */
+    UUID getEndpointUUIDProp(const std::string& service,
+                             const std::string& path);
+
     static constexpr uint8_t mctpTypePLDM = 1;
 };