rtu: implement modbus rtu inventory source service

Implement phosphor-modbus-rtu inventory source service based on [1].

[1]: https://gerrit.openbmc.org/c/openbmc/docs/+/77318

Tested: Unit test passes and tested on qemu with simulated modbus
server.
```
root@bmc:~# busctl tree xyz.openbmc_project.ModbusRTU
└─ /xyz
  └─ /xyz/openbmc_project
    └─ /xyz/openbmc_project/inventory_source
      └─ /xyz/openbmc_project/inventory_source/modbus
        ├─ /xyz/openbmc_project/inventory_source/modbus/Heat_Exchanger_12_DevTTYUSB0
        ├─ /xyz/openbmc_project/inventory_source/modbus/Heat_Exchanger_12_DevTTYUSB1
        ├─ /xyz/openbmc_project/inventory_source/modbus/Reservoir_Pumping_Unit_12_DevTTYUSB0
        └─ /xyz/openbmc_project/inventory_source/modbus/Reservoir_Pumping_Unit_12_DevTTYUSB1
root@bmc:~# busctl tree xyz.openbmc_project.EntityManager
└─ /xyz
  └─ /xyz/openbmc_project
    ├─ /xyz/openbmc_project/EntityManager
    └─ /xyz/openbmc_project/inventory
      └─ /xyz/openbmc_project/inventory/system
        ├─ /xyz/openbmc_project/inventory/system/board
        │ └─ /xyz/openbmc_project/inventory/system/board/Ventura_Modbus
        │   ├─ /xyz/openbmc_project/inventory/system/board/Ventura_Modbus/DevTTYUSB0
        │   ├─ /xyz/openbmc_project/inventory/system/board/Ventura_Modbus/DevTTYUSB1
        │   ├─ /xyz/openbmc_project/inventory/system/board/Ventura_Modbus/Heat_Exchanger
        │   └─ /xyz/openbmc_project/inventory/system/board/Ventura_Modbus/Reservoir_Pumping_Unit
        └─ /xyz/openbmc_project/inventory/system/chassis
          ├─ /xyz/openbmc_project/inventory/system/chassis/Heat_Exchanger_12_DevTTYUSB0
          ├─ /xyz/openbmc_project/inventory/system/chassis/Heat_Exchanger_12_DevTTYUSB1
          ├─ /xyz/openbmc_project/inventory/system/chassis/Reservoir_Pumping_Unit_12_DevTTYUSB0
          └─ /xyz/openbmc_project/inventory/system/chassis/Reservoir_Pumping_Unit_12_DevTTYUSB1

root@bmc:~# busctl introspect xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory/system/chassis/Heat_Exchanger_12_DevTTYUSB0
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.AddObject                 interface -         -                                        -
.AddObject                                    method    a{sv}     -                                        -
xyz.openbmc_project.Inventory.Decorator.Asset interface -         -                                        -
.BuildDate                                    property  s         "Unknown"                                emits-change
.Manufacturer                                 property  s         "Unknown"                                emits-change
.Model                                        property  s         "Unknown"                                emits-change
.PartNumber                                   property  s         "Unknown"                                emits-change
.SerialNumber                                 property  s         "Unknown"                                emits-change
.SparePartNumber                              property  s         "ABABABAB"                               emits-change
xyz.openbmc_project.Inventory.Item.Chassis    interface -         -                                        -
.Name                                         property  s         "Heat Exchanger 12 DevTTYUSB0"           emits-change
.Probe                                        property  s         "xyz.openbmc_project.Inventory.Source.M… emits-change
.Type                                         property  s         "Chassis"                                emits-change
root@bmc:~# busctl introspect xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory/system/chassis/Heat_Exchanger_12_DevTTYUSB1
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.AddObject                 interface -         -                                        -
.AddObject                                    method    a{sv}     -                                        -
xyz.openbmc_project.Inventory.Decorator.Asset interface -         -                                        -
.BuildDate                                    property  s         "Unknown"                                emits-change
.Manufacturer                                 property  s         "Unknown"                                emits-change
.Model                                        property  s         "Unknown"                                emits-change
.PartNumber                                   property  s         "Unknown"                                emits-change
.SerialNumber                                 property  s         "Unknown"                                emits-change
.SparePartNumber                              property  s         "ABABABAB"                               emits-change
xyz.openbmc_project.Inventory.Item.Chassis    interface -         -                                        -
.Name                                         property  s         "Heat Exchanger 12 DevTTYUSB1"           emits-change
.Probe                                        property  s         "xyz.openbmc_project.Inventory.Source.M… emits-change
.Type                                         property  s         "Chassis"                                emits-change

root@bmc:~# busctl introspect xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory/system/chassis/Reservoir_Pumping_Unit_12_DevTTYUSB0
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.AddObject                 interface -         -                                        -
.AddObject                                    method    a{sv}     -                                        -
xyz.openbmc_project.Inventory.Decorator.Asset interface -         -                                        -
.BuildDate                                    property  s         "ABABABAB"                               emits-change
.Manufacturer                                 property  s         "Unknown"                                emits-change
.Model                                        property  s         "ABABABABABABABAB"                       emits-change
.PartNumber                                   property  s         "Unknown"                                emits-change
.SerialNumber                                 property  s         "ABABABABABABABAB"                       emits-change
.SparePartNumber                              property  s         "ABABABAB"                               emits-change
xyz.openbmc_project.Inventory.Item.Chassis    interface -         -                                        -
.Name                                         property  s         "Reservoir Pumping Unit 12 DevTTYUSB0"   emits-change
.Probe                                        property  s         "xyz.openbmc_project.Inventory.Source.M… emits-change
.Type                                         property  s         "Chassis"                                emits-change
root@bmc:~# busctl introspect xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory/system/chassis/Reservoir_Pumping_Unit_12_DevTTYUSB1
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.AddObject                 interface -         -                                        -
.AddObject                                    method    a{sv}     -                                        -
xyz.openbmc_project.Inventory.Decorator.Asset interface -         -                                        -
.BuildDate                                    property  s         "ABABABAB"                               emits-change
.Manufacturer                                 property  s         "Unknown"                                emits-change
.Model                                        property  s         "ABABABABABABABAB"                       emits-change
.PartNumber                                   property  s         "Unknown"                                emits-change
.SerialNumber                                 property  s         "ABABABABABABABAB"                       emits-change
.SparePartNumber                              property  s         "ABABABAB"                               emits-change
xyz.openbmc_project.Inventory.Item.Chassis    interface -         -                                        -
.Name                                         property  s         "Reservoir Pumping Unit 12 DevTTYUSB1"   emits-change
.Probe                                        property  s         "xyz.openbmc_project.Inventory.Source.M… emits-change
.Type                                         property  s         "Chassis"                                emits-change
```

Change-Id: Ic0ea739de3833044c95da8164be1e2f3f8e6a063
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
diff --git a/rtu/inventory/modbus_inventory.hpp b/rtu/inventory/modbus_inventory.hpp
new file mode 100644
index 0000000..ed909c7
--- /dev/null
+++ b/rtu/inventory/modbus_inventory.hpp
@@ -0,0 +1,92 @@
+#pragma once
+
+#include "modbus/modbus.hpp"
+#include "port/base_port.hpp"
+
+#include <sdbusplus/async.hpp>
+#include <xyz/openbmc_project/Inventory/Source/Modbus/FRU/aserver.hpp>
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
+namespace phosphor::modbus::rtu::inventory
+{
+
+class Device;
+
+namespace ModbusIntf = phosphor::modbus::rtu;
+using SerialPortIntf = phosphor::modbus::rtu::port::BasePort;
+using InventorySourceIntf =
+    sdbusplus::aserver::xyz::openbmc_project::inventory::source::modbus::FRU<
+        Device>;
+
+namespace config
+{
+
+struct Register
+{
+    std::string name = "unknown";
+    uint16_t offset = 0;
+    uint8_t size = 0;
+};
+
+struct AddressRange
+{
+    uint8_t start;
+    uint8_t end;
+};
+
+struct Config
+{
+    using address_range_arr_t = std::vector<AddressRange>;
+    using port_address_map_t =
+        std::map<std::string,
+                 address_range_arr_t>; // <port name, device address range list>
+
+    std::string name = "unknown";
+    port_address_map_t addressMap = {};
+    std::vector<Register> registers = {};
+    ModbusIntf::Parity parity = ModbusIntf::Parity::unknown;
+    uint32_t baudRate = 0;
+};
+
+auto getConfig(sdbusplus::async::context& ctx,
+               sdbusplus::message::object_path objectPath)
+    -> sdbusplus::async::task<std::optional<Config>>;
+
+} // namespace config
+
+class Device
+{
+  public:
+    Device() = delete;
+    using serial_port_map_t =
+        std::unordered_map<std::string, std::unique_ptr<SerialPortIntf>>;
+
+    explicit Device(sdbusplus::async::context& ctx,
+                    const config::Config& config,
+                    serial_port_map_t& serialPorts);
+
+    auto probePorts() -> sdbusplus::async::task<void>;
+
+    auto probePort(std::string portName) -> sdbusplus::async::task<void>;
+
+    auto probeDevice(uint8_t address, const std::string& portName,
+                     SerialPortIntf& port) -> sdbusplus::async::task<void>;
+
+    auto addInventorySource(uint8_t address, const std::string& portName,
+                            SerialPortIntf& port)
+        -> sdbusplus::async::task<void>;
+
+  private:
+    sdbusplus::async::context& ctx;
+    const config::Config config;
+    serial_port_map_t& serialPorts;
+    std::map<std::string, std::unique_ptr<InventorySourceIntf>>
+        inventorySources;
+};
+
+} // namespace phosphor::modbus::rtu::inventory