Nvidia-Gpu: Support for Nvidia GPU Serial Number, Part Number

Support for serial number and part number fetch is added in inventory
class which uses the Get Inventory Command. Currently we have a retry
policy of 3 retires to account of any failures to get response from the
GPU device.

Tested
- Able to get Serial Number, Part Number updated from the GPU device

```
 busctl introspect xyz.openbmc_project.GpuSensor  /xyz/openbmc_project/inventory/NVIDIA_GB200_GPU_0
NAME                                                 TYPE      SIGNATURE RESULT/VALUE            FLAGS
org.freedesktop.DBus.Introspectable                  interface -         -                       -
.Introspect                                          method    -         s                       -
org.freedesktop.DBus.Peer                            interface -         -                       -
.GetMachineId                                        method    -         s                       -
.Ping                                                method    -         -                       -
org.freedesktop.DBus.Properties                      interface -         -                       -
.Get                                                 method    ss        v                       -
.GetAll                                              method    s         a{sv}                   -
.Set                                                 method    ssv       -                       -
.PropertiesChanged                                   signal    sa{sv}as  -                       -
xyz.openbmc_project.Inventory.Decorator.Asset        interface -         -                       -
.PartNumber                                          property  s         "699-2G153-0210-TS1"                     emits-change
.SerialNumber                                        property  s         "1330325220002"                          emits-change
xyz.openbmc_project.Inventory.Item.Accelerator       interface -         -                       -
.Type                                                property  s         "GPU"                   emits-change

```

Change-Id: Id2b33a66ff6d5480f8e229fa233528afc0bdcfc0
Signed-off-by: Rohit PAI <ropai@nvidia.com>
diff --git a/src/nvidia-gpu/Inventory.hpp b/src/nvidia-gpu/Inventory.hpp
index 8de490d..1d2587b 100644
--- a/src/nvidia-gpu/Inventory.hpp
+++ b/src/nvidia-gpu/Inventory.hpp
@@ -1,23 +1,72 @@
 #pragma once
 
+#include "MctpRequester.hpp"
 #include "NvidiaGpuMctpVdm.hpp"
 
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/asio/object_server.hpp>
 
+#include <array>
+#include <chrono>
+#include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
+#include <unordered_map>
 
-class Inventory
+using InventoryRequestBuffer =
+    std::array<uint8_t, sizeof(gpu::GetInventoryInformationRequest)>;
+using InventoryResponseBuffer =
+    std::array<uint8_t, sizeof(gpu::GetInventoryInformationResponse)>;
+
+class Inventory : public std::enable_shared_from_this<Inventory>
 {
   public:
     Inventory(const std::shared_ptr<sdbusplus::asio::connection>& conn,
               sdbusplus::asio::object_server& objectServer,
               const std::string& inventoryName,
-              gpu::DeviceIdentification deviceType);
+              mctp::MctpRequester& mctpRequester,
+              gpu::DeviceIdentification deviceType, uint8_t eid,
+              boost::asio::io_context& io);
 
   private:
+    struct PropertyInfo
+    {
+        std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
+        std::string propertyName;
+        int retryCount{0};
+        bool isPending{false};
+    };
+    void sendInventoryPropertyRequest(gpu::InventoryPropertyId propertyId);
+    void handleInventoryPropertyResponse(gpu::InventoryPropertyId propertyId,
+                                         int sendRecvMsgResult);
+    void processNextProperty();
+    void processInventoryProperty(gpu::InventoryPropertyId propertyId);
+    void registerProperty(
+        gpu::InventoryPropertyId propertyId,
+        const std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
+        const std::string& propertyName);
+    std::optional<gpu::InventoryPropertyId> getNextPendingProperty() const;
+    static void markPropertyPending(
+        std::unordered_map<gpu::InventoryPropertyId, PropertyInfo>::iterator
+            it);
+    static void markPropertyProcessed(
+        std::unordered_map<gpu::InventoryPropertyId, PropertyInfo>::iterator
+            it);
+
+    std::shared_ptr<sdbusplus::asio::dbus_interface> assetIface;
     std::shared_ptr<sdbusplus::asio::dbus_interface> acceleratorInterface;
 
     std::string name;
+    mctp::MctpRequester& mctpRequester;
+    gpu::DeviceIdentification deviceType;
+    uint8_t eid;
+    boost::asio::steady_timer retryTimer;
+    std::unordered_map<gpu::InventoryPropertyId, PropertyInfo> properties;
+    std::shared_ptr<InventoryRequestBuffer> requestBuffer;
+    std::shared_ptr<InventoryResponseBuffer> responseBuffer;
+    static constexpr std::chrono::seconds retryDelay{5};
+    static constexpr int maxRetryAttempts = 3;
 };