bm_instance: Create a new handler
This OEM handler will get properties from tmpfs to serve over IPMI.
Tested:
~# cat /run/bm-instance/asset-tag
12345
~# ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x17 0x00
79 2b 00 17 05 31 32 33 34 35
...
...
(Verified this works for all 7 sub commands)
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I191b6f4994d91ada49a3332a8e93a3a305561904
diff --git a/bm_instance.cpp b/bm_instance.cpp
new file mode 100644
index 0000000..d3fbd8e
--- /dev/null
+++ b/bm_instance.cpp
@@ -0,0 +1,76 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "bm_instance.hpp"
+
+#include "commands.hpp"
+#include "errors.hpp"
+#include "handler.hpp"
+
+#include <ipmid/api-types.hpp>
+#include <stdplus/print.hpp>
+
+#include <span>
+#include <vector>
+
+namespace google
+{
+namespace ipmi
+{
+
+namespace
+{
+#ifndef MAX_IPMI_BUFFER
+#define MAX_IPMI_BUFFER 64
+#endif
+} // namespace
+
+struct BMInstancePropertyRequest
+{
+ std::uint8_t bmInstancePropertyType;
+} __attribute__((packed));
+
+Resp getBMInstanceProperty(std::span<const uint8_t> data,
+ HandlerInterface* handler)
+{
+ if (data.size() < sizeof(struct BMInstancePropertyRequest))
+ {
+ stdplus::print(stderr, "Invalid command length: {}\n",
+ static_cast<uint32_t>(data.size()));
+ return ::ipmi::responseReqDataLenInvalid();
+ }
+
+ std::string bmInstanceProperty =
+ handler->getBMInstanceProperty(/*type=*/data[0]);
+
+ const size_t length = sizeof(struct BMInstancePropertyReply) +
+ bmInstanceProperty.size();
+
+ if (length > MAX_IPMI_BUFFER)
+ {
+ stdplus::print(stderr, "Response would overflow response buffer\n");
+ return ::ipmi::responseInvalidCommand();
+ }
+
+ std::vector<std::uint8_t> reply;
+ reply.reserve(length);
+ reply.emplace_back(bmInstanceProperty.size());
+ reply.insert(reply.end(), bmInstanceProperty.begin(),
+ bmInstanceProperty.end());
+
+ return ::ipmi::responseSuccess(SysOEMCommands::SysGetBMInstanceProperty,
+ reply);
+}
+} // namespace ipmi
+} // namespace google