xref: /openbmc/google-ipmi-sys/bm_instance.cpp (revision 8c0094e4eb82029af1d111d2736111cbdda59b63)
1  // Copyright 2024 Google LLC
2  //
3  // Licensed under the Apache License, Version 2.0 (the "License");
4  // you may not use this file except in compliance with the License.
5  // You may obtain a copy of the License at
6  //
7  //      http://www.apache.org/licenses/LICENSE-2.0
8  //
9  // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  #include "bm_instance.hpp"
16  
17  #include "commands.hpp"
18  #include "errors.hpp"
19  #include "handler.hpp"
20  
21  #include <ipmid/api-types.hpp>
22  #include <stdplus/print.hpp>
23  
24  #include <span>
25  #include <vector>
26  
27  namespace google
28  {
29  namespace ipmi
30  {
31  
32  namespace
33  {
34  #ifndef MAX_IPMI_BUFFER
35  #define MAX_IPMI_BUFFER 64
36  #endif
37  } // namespace
38  
39  struct BMInstancePropertyRequest
40  {
41      std::uint8_t bmInstancePropertyType;
42  } __attribute__((packed));
43  
getBMInstanceProperty(std::span<const uint8_t> data,HandlerInterface * handler)44  Resp getBMInstanceProperty(std::span<const uint8_t> data,
45                             HandlerInterface* handler)
46  {
47      if (data.size() < sizeof(struct BMInstancePropertyRequest))
48      {
49          stdplus::print(stderr, "Invalid command length: {}\n",
50                         static_cast<uint32_t>(data.size()));
51          return ::ipmi::responseReqDataLenInvalid();
52      }
53  
54      std::string bmInstanceProperty =
55          handler->getBMInstanceProperty(/*type=*/data[0]);
56  
57      const size_t length =
58          sizeof(struct BMInstancePropertyReply) + bmInstanceProperty.size();
59  
60      if (length > MAX_IPMI_BUFFER)
61      {
62          stdplus::print(stderr, "Response would overflow response buffer\n");
63          return ::ipmi::responseInvalidCommand();
64      }
65  
66      std::vector<std::uint8_t> reply;
67      reply.reserve(length);
68      reply.emplace_back(bmInstanceProperty.size());
69      reply.insert(reply.end(), bmInstanceProperty.begin(),
70                   bmInstanceProperty.end());
71  
72      return ::ipmi::responseSuccess(SysOEMCommands::SysGetBMInstanceProperty,
73                                     reply);
74  }
75  } // namespace ipmi
76  } // namespace google
77