requester: support get DBus inventory object path from mctp-repactor

mctp-reactor is a new daemon which will replace legacy mctp-i2c service
to setup MCTP endoints and build accocsation between MCTP endpoint and
DBus inventory object path.

Tested:
https://paste.googleplex.com/5000364277497856

Google-Bug-Id: 404864633
Google-Bug-Id: 443117191
Change-Id: I201df2c383d9e0595a9ead696e0888393ba17ca0
Signed-off-by: Jinliang Wang <jinliangw@google.com>
diff --git a/requester/terminus_manager.hpp b/requester/terminus_manager.hpp
index 2685b25..90e159b 100644
--- a/requester/terminus_manager.hpp
+++ b/requester/terminus_manager.hpp
@@ -88,6 +88,49 @@
         file.close();
     }
 
+    std::string getInventoryPathFromMctpReactor(mctp_eid_t eid)
+    {
+        const std::string eidConfiguredBy =
+            "/au/com/codeconstruct/mctp1/networks/1/endpoints/" +
+            std::to_string(eid) + "/configured_by";
+        for (int retry = 1; retry <= 3; retry++)
+        {
+            try
+            {
+                auto propVal = utils::DBusHandler().getDbusPropertyVariant(
+                    eidConfiguredBy.c_str(), "endpoints",
+                    "xyz.openbmc_project.Association");
+                if (!std::holds_alternative<std::vector<std::string>>(propVal))
+                {
+                    std::cerr
+                        << "Error: unexpected Association endpoints property value\n";
+                    return {};
+                }
+                const auto& endpoints =
+                    std::get<std::vector<std::string>>(propVal);
+                if (endpoints.size() != 1)
+                {
+                    std::cerr << "Error: unexpected Association endpoints size:"
+                              << endpoints.size() << "\n";
+                    return {};
+                }
+
+                return endpoints[0];
+            }
+            catch (const sdbusplus::exception_t& e)
+            {
+                std::cerr << std::format(
+                    "Error in getting {}  Association endpoints, e.what(): {}, retry={} \n",
+                    eidConfiguredBy, e.what(), retry);
+                // 100ms, 200ms, 300ms = 600ms
+                std::this_thread::sleep_for(
+                    std::chrono::milliseconds(retry * 100));
+            }
+        }
+
+        return {};
+    }
+
     /** @brief Add the discovered MCTP endpoints to the managed devices list
      *
      *  @param[in] eids - Array of MCTP endpoints
@@ -116,11 +159,30 @@
             }
             dev->udpateEidMapping(eidMap);
 
+            std::string inventoryPath;
             if (eidToInventory.count(it))
             {
-                dev->setInventoryPath(eidToInventory[it]);
+                // From legacy mctp-i2c.service
+                inventoryPath = eidToInventory[it];
+            }
+            else
+            {
+                // From new xyz.openbmc_project.mctpreactor.service
+                inventoryPath = getInventoryPathFromMctpReactor(it);
+            }
+
+            if (!inventoryPath.empty())
+            {
+                dev->setInventoryPath(inventoryPath);
                 dev->loadAuxNameMapping();
             }
+            else
+            {
+                std::cerr
+                    << "Error: Cannot find inventory DBus object path for EID "
+                    << unsigned(it) << ", skipped creating terminus device\n";
+                continue;
+            }
 
             [[maybe_unused]] auto co = dev->discoveryTerminus();
             dev->startSensorsPolling();