Updated iei namespace
Change-Id: I9e623452279b363ee8421e2bd4d2072c2b44031f
Signed-off-by: George Liu <liuxiwei@ieisystem.com>
diff --git a/src/iei_oem.cpp b/src/iei_oem.cpp
new file mode 100644
index 0000000..36087a6
--- /dev/null
+++ b/src/iei_oem.cpp
@@ -0,0 +1,178 @@
+#include "config.h"
+
+#include "iei_oem.hpp"
+
+#include "sdbus_wrapper.hpp"
+#include "utils.hpp"
+
+#include <ipmid/api.h>
+
+#include <phosphor-logging/log.hpp>
+
+#include <optional>
+
+namespace
+{
+constexpr auto FIRMWARE_TYPE_OFFSET = 0;
+constexpr auto FIRMWARE_TYPE_SIZE = 1;
+constexpr auto FIRMWARE_VERSION_OFFSET =
+ FIRMWARE_TYPE_OFFSET + FIRMWARE_TYPE_SIZE;
+constexpr auto FIRMWARE_VERSION_SIZE = 15;
+constexpr auto FIRMWARE_BUILDTIME_OFFSET =
+ FIRMWARE_VERSION_OFFSET + FIRMWARE_VERSION_SIZE;
+constexpr auto FIRMWARE_BUILDTIME_SIZE = 20;
+constexpr auto FIRMWARE_MIN_SIZE = FIRMWARE_BUILDTIME_OFFSET;
+
+static_assert(FIRMWARE_VERSION_OFFSET == 1);
+static_assert(FIRMWARE_BUILDTIME_OFFSET == 16);
+} // namespace
+
+namespace ipmi
+{
+
+#define UNUSED(x) (void)(x)
+
+using namespace phosphor::logging;
+using namespace iei;
+
+static void registerOEMFunctions() __attribute__((constructor));
+static auto& bus = getBus();
+
+struct ParsedAssetInfo
+{
+ uint8_t rwFlag;
+ uint8_t deviceType;
+ uint8_t infoType;
+ uint8_t maskAllPresentLen;
+ std::vector<uint8_t> enableStatus;
+ std::vector<uint8_t> maskPresent;
+ std::vector<uint8_t> maskAllPresent;
+ uint8_t allInfoDone;
+ uint16_t totalMessageLen;
+ std::vector<uint8_t> data;
+};
+
+void dumpAssetInfo(const ParsedAssetInfo& info)
+{
+ fprintf(stderr,
+ "AssetInfo: rw %d, deviceType 0x%02x, infoType 0x%02x, "
+ "maskAllPresentLen %u\n",
+ info.rwFlag, info.deviceType, info.infoType,
+ info.maskAllPresentLen);
+ fprintf(stderr, "enableStatus ");
+ for (const auto& d : info.enableStatus)
+ {
+ fprintf(stderr, "0x%02x ", d);
+ }
+ fprintf(stderr, "\nmaskPresent ");
+ for (const auto& d : info.maskPresent)
+ {
+ fprintf(stderr, "0x%02x ", d);
+ }
+ fprintf(stderr, "\nmaskAllPresent ");
+ for (const auto& d : info.maskAllPresent)
+ {
+ fprintf(stderr, "0x%02x ", d);
+ }
+ fprintf(stderr, "\nallInfoDone %d, totalMessageLen %u\n", info.allInfoDone,
+ info.totalMessageLen);
+ fprintf(stderr, "data: ");
+ for (const auto& d : info.data)
+ {
+ fprintf(stderr, "0x%02x ", d);
+ }
+ fprintf(stderr, "\n");
+}
+
+std::optional<ParsedAssetInfo> parseAssetInfo(const AssetInfoHeader* h)
+{
+ auto len = h->maskAllPresentLen;
+ if (len == 0)
+ {
+ // This is invalid
+ return {};
+ }
+
+ ParsedAssetInfo info;
+ info.rwFlag = h->rwFlag;
+ info.deviceType = h->deviceType;
+ info.infoType = h->infoType;
+ info.maskAllPresentLen = len;
+ info.enableStatus.resize(len);
+ info.maskPresent.resize(len);
+ info.maskAllPresent.resize(len);
+ const uint8_t* p = &h->enableStatus;
+ memcpy(info.enableStatus.data(), p, len);
+ p += len;
+ memcpy(info.maskPresent.data(), p, len);
+ p += len;
+ memcpy(info.maskAllPresent.data(), p, len);
+ p += len;
+ info.allInfoDone = *p++;
+ info.totalMessageLen = *reinterpret_cast<const uint16_t*>(p);
+ p += sizeof(uint16_t);
+ auto dataLen = info.totalMessageLen - (sizeof(AssetInfoHeader) + 3 * len);
+ info.data.resize(dataLen);
+ memcpy(info.data.data(), p, dataLen);
+
+ // dumpAssetInfo(info);
+ return info;
+}
+
+void parseBIOSInfo(const std::vector<uint8_t>& data)
+{
+ if (data.size() < FIRMWARE_MIN_SIZE)
+ {
+ return;
+ }
+ bios_version_devname dev = static_cast<bios_version_devname>(data[0]);
+ std::string version{data.data() + FIRMWARE_VERSION_OFFSET,
+ data.data() + FIRMWARE_VERSION_SIZE};
+ std::string buildTime;
+ if (dev == bios_version_devname::BIOS)
+ {
+ buildTime.assign(reinterpret_cast<const char*>(
+ data.data() + FIRMWARE_BUILDTIME_OFFSET),
+ FIRMWARE_BUILDTIME_SIZE);
+
+ // Set BIOS version
+ auto service = utils::getService(bus, BIOS_OBJPATH, VERSION_IFACE);
+ utils::setProperty(bus, service.c_str(), BIOS_OBJPATH, VERSION_IFACE,
+ VERSION, version);
+ }
+
+ printf("Dev %s, version %s, build time %s\n",
+ bios_devname[static_cast<int>(dev)].data(), version.c_str(),
+ buildTime.c_str());
+}
+
+ipmi_ret_t ipmiOemIEIAssetInfo(ipmi_netfn_t /* netfn */, ipmi_cmd_t /* cmd */,
+ ipmi_request_t request, ipmi_response_t response,
+ ipmi_data_len_t /* data_len */,
+ ipmi_context_t /* context */)
+{
+ auto header = reinterpret_cast<AssetInfoHeader*>(request);
+ uint8_t* res = reinterpret_cast<uint8_t*>(response);
+ UNUSED(res);
+
+ auto info = parseAssetInfo(header);
+ auto deviceType = info->deviceType;
+ if (deviceType != 0x05)
+ {
+ log<level::WARNING>("Device type not supported yet");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ // For now we only support BIOS type
+ parseBIOSInfo(info->data);
+
+ return IPMI_CC_OK;
+}
+
+void registerOEMFunctions(void)
+{
+ ipmi_register_callback(NETFN_OEM_IEI, CMD_OEM_ASSET_INFO, nullptr,
+ ipmiOemIEIAssetInfo, SYSTEM_INTERFACE);
+}
+
+} // namespace ipmi