Implement command to retrieve firmware version
Currently, it only supports retrieving BMC/BIOS versions
Change-Id: I58bce16c491f18d27d3989e47814365de091954b
Signed-off-by: John Wang <wangzhiqiang02@ieisystem.com>
diff --git a/src/firmware_version.cpp b/src/firmware_version.cpp
new file mode 100644
index 0000000..fced513
--- /dev/null
+++ b/src/firmware_version.cpp
@@ -0,0 +1,95 @@
+#include "types.hpp"
+#include "utils.hpp"
+
+#include <ipmid/api.hpp>
+
+#include <regex>
+
+namespace ipmi
+{
+namespace iei
+{
+namespace firmware_version
+{
+
+void registerIEIFirmwareVersionFunctions() __attribute__((constructor));
+
+static constexpr auto versionInterface = "xyz.openbmc_project.Software.Version";
+
+std::string getBMCVersionValue(ipmi::Context::ptr ctx,
+ const std::string& objPath,
+ const std::string& interface)
+{
+ std::string value{};
+ auto cc = iei::getDbusProperty(ctx, objPath, interface, "Version", value);
+ if (cc)
+ {
+ return "";
+ }
+
+ const std::regex patternId("v[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}");
+ std::smatch result;
+ if (!std::regex_search(value, result, patternId))
+ {
+ return "";
+ }
+ std::string versionStr = result[0];
+ return versionStr.substr(1);
+}
+
+std::string getFWVersionValue(ipmi::Context::ptr ctx,
+ const std::string& objPath,
+ const std::string& interface)
+{
+ std::string value{};
+ auto cc = iei::getDbusProperty(ctx, objPath, interface, "Version", value);
+ if (cc)
+ {
+ return "";
+ }
+ return value;
+}
+
+enum FirmwareType : uint8_t
+{
+ BMC = 0x01,
+ BIOS = 0x03,
+};
+
+RspType<std::string> ipmiIEIGetFWVersion(ipmi::Context::ptr ctx,
+ uint8_t fwIndex,
+ uint8_t /* devIndex */)
+{
+ std::string fwPath{};
+ std::string value{};
+
+ switch (fwIndex)
+ {
+ case BMC:
+ {
+ fwPath = "/xyz/openbmc_project/software/bmc_active";
+ value = getBMCVersionValue(ctx, fwPath, versionInterface);
+ break;
+ }
+ case BIOS:
+ {
+ fwPath = "/xyz/openbmc_project/software/bios_active";
+ value = getFWVersionValue(ctx, fwPath, versionInterface);
+ break;
+ }
+ default:
+ return ipmi::responseParmOutOfRange();
+ }
+
+ return ipmi::responseSuccess(value);
+}
+
+void registerIEIFirmwareVersionFunctions()
+{
+ ipmi::registerHandler(prioOemBase, netFnIEI, cmdGetFWVersion,
+ ipmi::Privilege::User, ipmiIEIGetFWVersion);
+}
+
+} // namespace firmware_version
+} // namespace iei
+} // namespace ipmi