fw_update: Introduce FirmwareInventory
Spec reference: [1]
Description:
FirmwareInventory is a class that manages all of the D-Bus
utilities for the firmware update functionality of each entry,
FirmwareInventoryManager is used to manage multiple FirmwareInventory
instances.
Flow of the routine when one or more firmware device is added:
1. When one or more firmware device is added, the InventoryManager
instance will try to create a FirmwareInventory entry for the added
device, to accomplish this, it will need to fetch the necessary
information from various source (e.g. EM, device descriptors).
2. After the information is gathered, the InventoryManager will try to
obtain a Name for each firmware devices, to fit the different
platform condition, the name will be reference by the order below:
1. From Entity Manager (EM), if the endpoint has a specific EM
configuration with "Name" property listed.
2. From device descriptors, if the device descriptor contains a
vendor defined descriptor with "OpenBMC.Name" titled.
3. Spawn a default one, named "Firmware_Device_<Endpoint ID>".
3. The InventoryManager will then invoke
`FirmwareInventoryManager::createFirmwareInventory` to create a
firmware inventory entry.
Properties managed by firmware Inventory:
1. Version
Version object that represents the firmware version
2. Association
Association object that represents the associations for the
firmware
The object path pattern of the firmware inventory entry is:
`/xyz/openbmc_project/software/<BoardName>_<SoftwareName>_<SoftwareID>`
Where:
- `<BoardName>` represents the board the device is on.
- `<SoftwareName>` is the name of the firmware device obtained from the
InventoryManager.
- `<SoftwareID>` is a 4-byte random number to help consumer
distinguish from the new/old objects of a inventory item.
For example:
`server_board_slot_1_VR_2603`
The new Activation object and its related interfaces needs to
resides on a new objectPath, hence the softwareId is appended to
the path.
Test results:
- Build passed
- Successfully create firmware inventory entries
on Yosemite V4
[1]: https://github.com/openbmc/docs/blob/master/designs/code-update.md
Change-Id: Idebd7d013c82c60f08309a1860d5de1deeb3829a
Signed-off-by: Unive Tien <unive.tien.wiwynn@gmail.com>
Signed-off-by: Carter Chen <carter.chen.wiwynn@gmail.com>
diff --git a/fw-update/firmware_inventory_manager.hpp b/fw-update/firmware_inventory_manager.hpp
new file mode 100644
index 0000000..e6616ce
--- /dev/null
+++ b/fw-update/firmware_inventory_manager.hpp
@@ -0,0 +1,101 @@
+#pragma once
+
+#include "common/types.hpp"
+#include "firmware_inventory.hpp"
+
+class FirmwareInventoryManagerTest;
+
+namespace pldm::fw_update
+{
+
+using ObjectPath = pldm::dbus::ObjectPath;
+using SoftwareMap =
+ std::map<SoftwareIdentifier, std::unique_ptr<FirmwareInventory>>;
+
+/**
+ * @brief Get the Board path from Entity Manager for the given inventory path
+ * @param[in] path - Inventory path
+ * @param[in] handler - D-Bus handler for querying ancestors
+ * @return Board path if found, std::nullopt otherwise
+ */
+std::optional<std::filesystem::path> getBoardPath(
+ const pldm::utils::DBusHandler& handler, const InventoryPath& path);
+
+class FirmwareInventoryManager
+{
+ public:
+ friend class ::FirmwareInventoryManagerTest;
+ FirmwareInventoryManager() = delete;
+ FirmwareInventoryManager(const FirmwareInventoryManager&) = delete;
+ FirmwareInventoryManager(FirmwareInventoryManager&&) = delete;
+ FirmwareInventoryManager& operator=(const FirmwareInventoryManager&) =
+ delete;
+ FirmwareInventoryManager& operator=(FirmwareInventoryManager&&) = delete;
+ ~FirmwareInventoryManager() = default;
+
+ /**
+ * @brief Constructor
+ * @param[in] configurations - Reference to the EM configurations for MCTP
+ * endpoints
+ */
+ explicit FirmwareInventoryManager(
+ const pldm::utils::DBusHandler* dbusHandler,
+ const Configurations& config) :
+ dbusHandler(dbusHandler), configurations(config)
+ {}
+
+ /**
+ * @brief Creates a firmware inventory entry for the given software
+ * identifier
+ * @param[in] softwareIdentifier - Software identifier containing EID and
+ * component identifier
+ * @param[in] softwareName - Name of the firmware device
+ * @param[in] activeVersion - Active version of the firmware
+ * @param[in] descriptors - Descriptors associated with the firmware
+ * @param[in] componentInfo - Component information associated with the
+ * firmware
+ */
+ void createFirmwareEntry(
+ const SoftwareIdentifier& softwareIdentifier,
+ const SoftwareName& softwareName, const std::string& activeVersion,
+ const Descriptors& descriptors, const ComponentInfo& componentInfo);
+
+ /**
+ * @brief Deletes the firmware inventory entry for the given EID
+ * @param[in] eid - MCTP endpoint ID for which the firmware inventory entry
+ * needs to be deleted
+ */
+ void deleteFirmwareEntry(const pldm::eid& eid);
+
+ private:
+ /**
+ * @brief Get the inventory path associated with the given EID
+ * @param[in] eid - MCTP endpoint ID
+ * @return Inventory path if found, std::nullopt otherwise
+ */
+ std::optional<InventoryPath> getInventoryPath(const pldm::eid& eid) const;
+
+ /**
+ * @brief D-Bus Handler
+ */
+ const pldm::utils::DBusHandler* dbusHandler;
+
+ /**
+ * @brief Map of software identifier to FirmwareInventory instances
+ * This map maintains the firmware inventory entries created for
+ * different firmware components identified by their software
+ * identifiers (EID and component identifier).
+ */
+ SoftwareMap softwareMap;
+
+ /**
+ * @brief Reference to the EM configurations for MCTP endpoints
+ * This is used to retrieve the associated endpoint information
+ * when creating firmware inventory entries.
+ * It is expected that the configurations are provided during
+ * the initialization of the FirmwareInventoryManager.
+ */
+ const Configurations& configurations;
+};
+
+} // namespace pldm::fw_update