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