xref: /openbmc/google-ipmi-sys/google_accel_oob.cpp (revision d455bfd6e08dd09d10b220adc99d29ac33839e59)
14f0d1de6SSteve Foreman // Copyright 2022 Google LLC
24f0d1de6SSteve Foreman //
34f0d1de6SSteve Foreman // Licensed under the Apache License, Version 2.0 (the "License");
44f0d1de6SSteve Foreman // you may not use this file except in compliance with the License.
54f0d1de6SSteve Foreman // You may obtain a copy of the License at
64f0d1de6SSteve Foreman //
74f0d1de6SSteve Foreman //      http://www.apache.org/licenses/LICENSE-2.0
84f0d1de6SSteve Foreman //
94f0d1de6SSteve Foreman // Unless required by applicable law or agreed to in writing, software
104f0d1de6SSteve Foreman // distributed under the License is distributed on an "AS IS" BASIS,
114f0d1de6SSteve Foreman // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124f0d1de6SSteve Foreman // See the License for the specific language governing permissions and
134f0d1de6SSteve Foreman // limitations under the License.
144f0d1de6SSteve Foreman 
154f0d1de6SSteve Foreman #include "google_accel_oob.hpp"
164f0d1de6SSteve Foreman 
174f0d1de6SSteve Foreman #include "commands.hpp"
18*d455bfd6SGaurav Gandhi #include "errors.hpp"
19*d455bfd6SGaurav Gandhi #include "handler.hpp"
204f0d1de6SSteve Foreman 
21444b5ea4SPatrick Williams #include <sdbusplus/bus.hpp>
228d618532SMichael Shen #include <stdplus/print.hpp>
23444b5ea4SPatrick Williams 
244f0d1de6SSteve Foreman #include <cstdint>
254f0d1de6SSteve Foreman #include <cstring>
264f0d1de6SSteve Foreman #include <span>
274f0d1de6SSteve Foreman #include <string>
284f0d1de6SSteve Foreman #include <vector>
294f0d1de6SSteve Foreman 
304f0d1de6SSteve Foreman namespace google
314f0d1de6SSteve Foreman {
324f0d1de6SSteve Foreman namespace ipmi
334f0d1de6SSteve Foreman {
344f0d1de6SSteve Foreman 
354f0d1de6SSteve Foreman #ifndef MAX_IPMI_BUFFER
364f0d1de6SSteve Foreman #define MAX_IPMI_BUFFER 64
374f0d1de6SSteve Foreman #endif
384f0d1de6SSteve Foreman 
394f0d1de6SSteve Foreman // token + address(8) + num_bytes + data(8) + len + NULL
404f0d1de6SSteve Foreman constexpr size_t MAX_NAME_SIZE = MAX_IPMI_BUFFER - 1 - 8 - 1 - 8 - 1 - 1;
414f0d1de6SSteve Foreman 
accelOobDeviceCount(std::span<const uint8_t> data,HandlerInterface * handler)424f0d1de6SSteve Foreman Resp accelOobDeviceCount(std::span<const uint8_t> data,
434f0d1de6SSteve Foreman                          HandlerInterface* handler)
444f0d1de6SSteve Foreman {
454f0d1de6SSteve Foreman     struct Request
464f0d1de6SSteve Foreman     {
474f0d1de6SSteve Foreman     } __attribute__((packed));
484f0d1de6SSteve Foreman 
494f0d1de6SSteve Foreman     struct Reply
504f0d1de6SSteve Foreman     {
514f0d1de6SSteve Foreman         uint32_t count;
524f0d1de6SSteve Foreman     } __attribute__((packed));
534f0d1de6SSteve Foreman 
544f0d1de6SSteve Foreman     if (data.size_bytes() < sizeof(Request))
554f0d1de6SSteve Foreman     {
568d618532SMichael Shen         stdplus::print(stderr, "AccelOob DeviceCount command too small: {}\n",
574f0d1de6SSteve Foreman                        data.size_bytes());
584f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenInvalid();
594f0d1de6SSteve Foreman     }
604f0d1de6SSteve Foreman 
614f0d1de6SSteve Foreman     if (data.size_bytes() + sizeof(Reply) > MAX_IPMI_BUFFER)
624f0d1de6SSteve Foreman     {
638d618532SMichael Shen         stdplus::print(
648d618532SMichael Shen             stderr,
654f0d1de6SSteve Foreman             "AccelOob DeviceCount command too large for reply buffer: "
668d618532SMichael Shen             "command={}B, payload={}B, max={}B\n",
674f0d1de6SSteve Foreman             data.size_bytes(), sizeof(Reply), MAX_IPMI_BUFFER);
684f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenExceeded();
694f0d1de6SSteve Foreman     }
704f0d1de6SSteve Foreman 
714f0d1de6SSteve Foreman     uint32_t count = handler->accelOobDeviceCount();
724f0d1de6SSteve Foreman 
734f0d1de6SSteve Foreman     std::vector<uint8_t> replyBuf(sizeof(Reply));
744f0d1de6SSteve Foreman     auto* reply = reinterpret_cast<Reply*>(replyBuf.data());
754f0d1de6SSteve Foreman     reply->count = count;
764f0d1de6SSteve Foreman 
774f0d1de6SSteve Foreman     return ::ipmi::responseSuccess(SysOEMCommands::SysAccelOobDeviceCount,
784f0d1de6SSteve Foreman                                    replyBuf);
794f0d1de6SSteve Foreman }
804f0d1de6SSteve Foreman 
accelOobDeviceName(std::span<const uint8_t> data,HandlerInterface * handler)814f0d1de6SSteve Foreman Resp accelOobDeviceName(std::span<const uint8_t> data,
824f0d1de6SSteve Foreman                         HandlerInterface* handler)
834f0d1de6SSteve Foreman {
844f0d1de6SSteve Foreman     struct Request
854f0d1de6SSteve Foreman     {
864f0d1de6SSteve Foreman         uint32_t index;
874f0d1de6SSteve Foreman     } __attribute__((packed));
884f0d1de6SSteve Foreman 
894f0d1de6SSteve Foreman     struct Reply
904f0d1de6SSteve Foreman     {
914f0d1de6SSteve Foreman         uint8_t nameLength;
924f0d1de6SSteve Foreman         char name[MAX_NAME_SIZE];
934f0d1de6SSteve Foreman     } __attribute__((packed));
944f0d1de6SSteve Foreman 
954f0d1de6SSteve Foreman     if (data.size_bytes() < sizeof(Request))
964f0d1de6SSteve Foreman     {
978d618532SMichael Shen         stdplus::print(stderr, "AccelOob DeviceName command too small: {}\n",
984f0d1de6SSteve Foreman                        data.size_bytes());
994f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenInvalid();
1004f0d1de6SSteve Foreman     }
1014f0d1de6SSteve Foreman 
1024f0d1de6SSteve Foreman     if (data.size_bytes() + sizeof(Reply) > MAX_IPMI_BUFFER)
1034f0d1de6SSteve Foreman     {
1048d618532SMichael Shen         stdplus::print(
1058d618532SMichael Shen             stderr,
1064f0d1de6SSteve Foreman             "AccelOob DeviceName command too large for reply buffer: "
1078d618532SMichael Shen             "command={}B, payload={}B, max={}B\n",
1084f0d1de6SSteve Foreman             data.size_bytes(), sizeof(Reply), MAX_IPMI_BUFFER);
1094f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenExceeded();
1104f0d1de6SSteve Foreman     }
1114f0d1de6SSteve Foreman 
1124f0d1de6SSteve Foreman     auto* req = reinterpret_cast<const Request*>(data.data());
1134f0d1de6SSteve Foreman     std::string name = handler->accelOobDeviceName(req->index);
1144f0d1de6SSteve Foreman 
1154f0d1de6SSteve Foreman     if (name.size() > MAX_NAME_SIZE)
1164f0d1de6SSteve Foreman     {
1178d618532SMichael Shen         stdplus::print(stderr,
1184f0d1de6SSteve Foreman                        "AccelOob: name was too long. "
1198d618532SMichael Shen                        "'{}' len must be <= {}\n",
1208d618532SMichael Shen                        name, MAX_NAME_SIZE);
1214f0d1de6SSteve Foreman         return ::ipmi::responseReqDataTruncated();
1224f0d1de6SSteve Foreman     }
1234f0d1de6SSteve Foreman 
1244f0d1de6SSteve Foreman     std::vector<uint8_t> replyBuf(data.size_bytes() + sizeof(Reply));
1254f0d1de6SSteve Foreman     std::copy(data.begin(), data.end(), replyBuf.data());
1264f0d1de6SSteve Foreman     auto* reply = reinterpret_cast<Reply*>(replyBuf.data() + data.size_bytes());
1274f0d1de6SSteve Foreman     reply->nameLength = name.length();
1284f0d1de6SSteve Foreman     memcpy(reply->name, name.c_str(), reply->nameLength + 1);
1294f0d1de6SSteve Foreman 
1304f0d1de6SSteve Foreman     return ::ipmi::responseSuccess(SysOEMCommands::SysAccelOobDeviceName,
1314f0d1de6SSteve Foreman                                    replyBuf);
1324f0d1de6SSteve Foreman }
1334f0d1de6SSteve Foreman 
1344f0d1de6SSteve Foreman namespace
1354f0d1de6SSteve Foreman {
1364f0d1de6SSteve Foreman 
1374f0d1de6SSteve Foreman struct NameHeader
1384f0d1de6SSteve Foreman {
1394f0d1de6SSteve Foreman     uint8_t nameLength;
1404f0d1de6SSteve Foreman     char name[MAX_NAME_SIZE];
1414f0d1de6SSteve Foreman } __attribute__((packed));
1424f0d1de6SSteve Foreman 
1434f0d1de6SSteve Foreman // Reads the variable-length name from reqBuf and outputs the name and a pointer
1444f0d1de6SSteve Foreman // to the payload (next byte after name).
1454f0d1de6SSteve Foreman //
1464f0d1de6SSteve Foreman // Returns: =0: success.
1474f0d1de6SSteve Foreman //          >0: if dataLen is too small, returns the minimum buffers size.
1484f0d1de6SSteve Foreman //
1494f0d1de6SSteve Foreman // Params:
1504f0d1de6SSteve Foreman //    [in]  reqBuf      - the request buffer
1514f0d1de6SSteve Foreman //    [in]  dataLen     - the length of reqBuf, in bytes
1524f0d1de6SSteve Foreman //    [in]  payloadSize - the size of the expected payload
1534f0d1de6SSteve Foreman //    [out] name        - the name string
1544f0d1de6SSteve Foreman //    [out] payload     - pointer into reqBuf just after name
ReadNameHeader(const uint8_t * reqBuf,size_t dataLen,size_t payloadSize,std::string * name,const uint8_t ** payload)1554f0d1de6SSteve Foreman size_t ReadNameHeader(const uint8_t* reqBuf, size_t dataLen, size_t payloadSize,
1564f0d1de6SSteve Foreman                       std::string* name, const uint8_t** payload)
1574f0d1de6SSteve Foreman {
1584f0d1de6SSteve Foreman     constexpr size_t kNameHeaderSize = sizeof(NameHeader) - MAX_NAME_SIZE;
1594f0d1de6SSteve Foreman 
1604f0d1de6SSteve Foreman     auto* req_header = reinterpret_cast<const NameHeader*>(reqBuf);
1614f0d1de6SSteve Foreman 
1624f0d1de6SSteve Foreman     size_t minDataLen = kNameHeaderSize + payloadSize + req_header->nameLength;
1634f0d1de6SSteve Foreman     if (dataLen < minDataLen)
1644f0d1de6SSteve Foreman     {
1654f0d1de6SSteve Foreman         return minDataLen;
1664f0d1de6SSteve Foreman     }
1674f0d1de6SSteve Foreman 
1684f0d1de6SSteve Foreman     if (name)
1694f0d1de6SSteve Foreman     {
1704f0d1de6SSteve Foreman         *name = std::string(req_header->name, req_header->nameLength);
1714f0d1de6SSteve Foreman     }
1724f0d1de6SSteve Foreman     if (payload)
1734f0d1de6SSteve Foreman     {
1744f0d1de6SSteve Foreman         *payload = reqBuf + kNameHeaderSize + req_header->nameLength;
1754f0d1de6SSteve Foreman     }
1764f0d1de6SSteve Foreman     return 0;
1774f0d1de6SSteve Foreman }
1784f0d1de6SSteve Foreman 
1794f0d1de6SSteve Foreman } // namespace
1804f0d1de6SSteve Foreman 
accelOobRead(std::span<const uint8_t> data,HandlerInterface * handler)1814f0d1de6SSteve Foreman Resp accelOobRead(std::span<const uint8_t> data, HandlerInterface* handler)
1824f0d1de6SSteve Foreman {
1834f0d1de6SSteve Foreman     struct Request
1844f0d1de6SSteve Foreman     {
1854f0d1de6SSteve Foreman         // Variable length header, handled by ReadNameHeader
1864f0d1de6SSteve Foreman         // uint8_t  nameLength;  // <= MAX_NAME_SIZE
1874f0d1de6SSteve Foreman         // char     name[nameLength];
1884f0d1de6SSteve Foreman 
1894f0d1de6SSteve Foreman         // Additional arguments
1904f0d1de6SSteve Foreman         uint8_t token;
1914f0d1de6SSteve Foreman         uint64_t address;
1924f0d1de6SSteve Foreman         uint8_t num_bytes;
1934f0d1de6SSteve Foreman     } __attribute__((packed));
1944f0d1de6SSteve Foreman 
1954f0d1de6SSteve Foreman     struct Reply
1964f0d1de6SSteve Foreman     {
1974f0d1de6SSteve Foreman         uint64_t data;
1984f0d1de6SSteve Foreman     } __attribute__((packed));
1994f0d1de6SSteve Foreman 
2008d618532SMichael Shen     stdplus::print(stderr,
2014f0d1de6SSteve Foreman                    "AccelOob Read command sizes: "
2028d618532SMichael Shen                    "command={}B, payload={}B, max={}B\n",
2034f0d1de6SSteve Foreman                    data.size_bytes(), sizeof(Reply), MAX_IPMI_BUFFER);
2044f0d1de6SSteve Foreman 
2054f0d1de6SSteve Foreman     std::string name;
2064f0d1de6SSteve Foreman     const uint8_t* payload;
2074f0d1de6SSteve Foreman 
2084f0d1de6SSteve Foreman     size_t min_size = ReadNameHeader(data.data(), data.size_bytes(),
2094f0d1de6SSteve Foreman                                      sizeof(Request), &name, &payload);
2104f0d1de6SSteve Foreman     if (min_size != 0)
2114f0d1de6SSteve Foreman     {
2128d618532SMichael Shen         stdplus::print(stderr, "AccelOob Read command too small: {}B < {}B\n",
2134f0d1de6SSteve Foreman                        data.size_bytes(), min_size);
2144f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenInvalid();
2154f0d1de6SSteve Foreman     }
2164f0d1de6SSteve Foreman 
2174f0d1de6SSteve Foreman     if (data.size_bytes() + sizeof(Reply) > MAX_IPMI_BUFFER)
2184f0d1de6SSteve Foreman     {
2198d618532SMichael Shen         stdplus::print(stderr,
2204f0d1de6SSteve Foreman                        "AccelOob Read command too large for reply buffer: "
2218d618532SMichael Shen                        "command={}B, payload={}B, max={}B\n",
2224f0d1de6SSteve Foreman                        data.size_bytes(), sizeof(Reply), MAX_IPMI_BUFFER);
2234f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenExceeded();
2244f0d1de6SSteve Foreman     }
2254f0d1de6SSteve Foreman 
2264f0d1de6SSteve Foreman     auto req = reinterpret_cast<const Request*>(payload);
2274f0d1de6SSteve Foreman     uint64_t r = handler->accelOobRead(name, req->address, req->num_bytes);
2284f0d1de6SSteve Foreman 
2294f0d1de6SSteve Foreman     std::vector<uint8_t> replyBuf(data.size_bytes() + sizeof(Reply));
2304f0d1de6SSteve Foreman     std::copy(data.begin(), data.end(), replyBuf.data());
2314f0d1de6SSteve Foreman     auto* reply = reinterpret_cast<Reply*>(replyBuf.data() + data.size_bytes());
2324f0d1de6SSteve Foreman     reply->data = r;
2334f0d1de6SSteve Foreman 
2344f0d1de6SSteve Foreman     return ::ipmi::responseSuccess(SysOEMCommands::SysAccelOobRead, replyBuf);
2354f0d1de6SSteve Foreman }
2364f0d1de6SSteve Foreman 
accelOobWrite(std::span<const uint8_t> data,HandlerInterface * handler)2374f0d1de6SSteve Foreman Resp accelOobWrite(std::span<const uint8_t> data, HandlerInterface* handler)
2384f0d1de6SSteve Foreman {
2394f0d1de6SSteve Foreman     struct Request
2404f0d1de6SSteve Foreman     {
2414f0d1de6SSteve Foreman         // Variable length header, handled by ReadNameHeader
2424f0d1de6SSteve Foreman         // uint8_t  nameLength;  // <= MAX_NAME_SIZE
2434f0d1de6SSteve Foreman         // char     name[nameLength];
2444f0d1de6SSteve Foreman 
2454f0d1de6SSteve Foreman         // Additional arguments
2464f0d1de6SSteve Foreman         uint8_t token;
2474f0d1de6SSteve Foreman         uint64_t address;
2484f0d1de6SSteve Foreman         uint8_t num_bytes;
2494f0d1de6SSteve Foreman         uint64_t data;
2504f0d1de6SSteve Foreman     } __attribute__((packed));
2514f0d1de6SSteve Foreman 
2524f0d1de6SSteve Foreman     struct Reply
2534f0d1de6SSteve Foreman     {
2544f0d1de6SSteve Foreman         // Empty
2554f0d1de6SSteve Foreman     } __attribute__((packed));
2564f0d1de6SSteve Foreman 
2574f0d1de6SSteve Foreman     std::string name{};
2584f0d1de6SSteve Foreman     const uint8_t* payload;
2594f0d1de6SSteve Foreman 
2604f0d1de6SSteve Foreman     size_t min_size = ReadNameHeader(data.data(), data.size_bytes(),
2614f0d1de6SSteve Foreman                                      sizeof(Request), &name, &payload);
2624f0d1de6SSteve Foreman     if (min_size != 0)
2634f0d1de6SSteve Foreman     {
2648d618532SMichael Shen         stdplus::print(stderr, "AccelOob Write command too small: {}B < {}B\n",
2654f0d1de6SSteve Foreman                        data.size_bytes(), min_size);
2664f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenInvalid();
2674f0d1de6SSteve Foreman     }
2684f0d1de6SSteve Foreman 
2694f0d1de6SSteve Foreman     if (data.size_bytes() + sizeof(Reply) > MAX_IPMI_BUFFER)
2704f0d1de6SSteve Foreman     {
2718d618532SMichael Shen         stdplus::print(stderr,
2724f0d1de6SSteve Foreman                        "AccelOob Write command too large for reply buffer: "
2738d618532SMichael Shen                        "command={}B, payload={}B, max={}B\n",
2744f0d1de6SSteve Foreman                        data.size_bytes(), sizeof(Reply), MAX_IPMI_BUFFER);
2754f0d1de6SSteve Foreman         return ::ipmi::responseReqDataLenExceeded();
2764f0d1de6SSteve Foreman     }
2774f0d1de6SSteve Foreman 
2784f0d1de6SSteve Foreman     auto req = reinterpret_cast<const Request*>(payload);
2794f0d1de6SSteve Foreman     handler->accelOobWrite(name, req->address, req->num_bytes, req->data);
2804f0d1de6SSteve Foreman 
2814f0d1de6SSteve Foreman     std::vector<uint8_t> replyBuf(data.size_bytes() + sizeof(Reply));
2824f0d1de6SSteve Foreman     std::copy(data.begin(), data.end(), replyBuf.data());
2834f0d1de6SSteve Foreman 
2844f0d1de6SSteve Foreman     return ::ipmi::responseSuccess(SysOEMCommands::SysAccelOobWrite, replyBuf);
2854f0d1de6SSteve Foreman }
2864f0d1de6SSteve Foreman 
accelGetVrSettings(::ipmi::Context::ptr ctx,std::span<const uint8_t> data,HandlerInterface * handler)287*d455bfd6SGaurav Gandhi Resp accelGetVrSettings(::ipmi::Context::ptr ctx, std::span<const uint8_t> data,
288*d455bfd6SGaurav Gandhi                         HandlerInterface* handler)
289*d455bfd6SGaurav Gandhi {
290*d455bfd6SGaurav Gandhi     uint16_t value;
291*d455bfd6SGaurav Gandhi     if (data.size_bytes() != 2)
292*d455bfd6SGaurav Gandhi     {
293*d455bfd6SGaurav Gandhi         stdplus::println(
294*d455bfd6SGaurav Gandhi             stderr,
295*d455bfd6SGaurav Gandhi             "accelGetVrSettings command has incorrect size: %zuB != %dB\n",
296*d455bfd6SGaurav Gandhi             data.size_bytes(), 2);
297*d455bfd6SGaurav Gandhi         return ::ipmi::responseReqDataLenInvalid();
298*d455bfd6SGaurav Gandhi     }
299*d455bfd6SGaurav Gandhi 
300*d455bfd6SGaurav Gandhi     try
301*d455bfd6SGaurav Gandhi     {
302*d455bfd6SGaurav Gandhi         value = handler->accelGetVrSettings(ctx, /*chip_id*/ data[0],
303*d455bfd6SGaurav Gandhi                                             /*settings_id*/ data[1]);
304*d455bfd6SGaurav Gandhi     }
305*d455bfd6SGaurav Gandhi     catch (const IpmiException& e)
306*d455bfd6SGaurav Gandhi     {
307*d455bfd6SGaurav Gandhi         return ::ipmi::response(e.getIpmiError());
308*d455bfd6SGaurav Gandhi     }
309*d455bfd6SGaurav Gandhi     return ::ipmi::responseSuccess(
310*d455bfd6SGaurav Gandhi         SysOEMCommands::SysGetAccelVrSettings,
311*d455bfd6SGaurav Gandhi         std::vector<uint8_t>{static_cast<uint8_t>(value),
312*d455bfd6SGaurav Gandhi                              static_cast<uint8_t>(value >> 8)});
313*d455bfd6SGaurav Gandhi }
314*d455bfd6SGaurav Gandhi 
accelSetVrSettings(::ipmi::Context::ptr ctx,std::span<const uint8_t> data,HandlerInterface * handler)315*d455bfd6SGaurav Gandhi Resp accelSetVrSettings(::ipmi::Context::ptr ctx, std::span<const uint8_t> data,
316*d455bfd6SGaurav Gandhi                         HandlerInterface* handler)
317*d455bfd6SGaurav Gandhi {
318*d455bfd6SGaurav Gandhi     if (data.size_bytes() != 4)
319*d455bfd6SGaurav Gandhi     {
320*d455bfd6SGaurav Gandhi         stdplus::println(
321*d455bfd6SGaurav Gandhi             stderr,
322*d455bfd6SGaurav Gandhi             "accelSetVrSettings command has incorrect size: %zuB != %dB\n",
323*d455bfd6SGaurav Gandhi             data.size_bytes(), 4);
324*d455bfd6SGaurav Gandhi         return ::ipmi::responseReqDataLenInvalid();
325*d455bfd6SGaurav Gandhi     }
326*d455bfd6SGaurav Gandhi     uint16_t value = static_cast<uint16_t>(data[2] | data[3] << 8);
327*d455bfd6SGaurav Gandhi     try
328*d455bfd6SGaurav Gandhi     {
329*d455bfd6SGaurav Gandhi         handler->accelSetVrSettings(ctx, /*chip_id*/ data[0],
330*d455bfd6SGaurav Gandhi                                     /*settings_id*/ data[1], /*value*/ value);
331*d455bfd6SGaurav Gandhi     }
332*d455bfd6SGaurav Gandhi     catch (const IpmiException& e)
333*d455bfd6SGaurav Gandhi     {
334*d455bfd6SGaurav Gandhi         return ::ipmi::response(e.getIpmiError());
335*d455bfd6SGaurav Gandhi     }
336*d455bfd6SGaurav Gandhi     return ::ipmi::responseSuccess(SysOEMCommands::SysSetAccelVrSettings,
337*d455bfd6SGaurav Gandhi                                    std::vector<uint8_t>{});
338*d455bfd6SGaurav Gandhi }
3394f0d1de6SSteve Foreman } // namespace ipmi
3404f0d1de6SSteve Foreman } // namespace google
341