cpld.cpp (a2056e9ca86e767a774d621c5117939562c5aa54) cpld.cpp (ff3cd8e91958cadd6a9f72f2ad69c00abae3c7cf)
1// Copyright 2021 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//

--- 5 unchanged lines hidden (view full) ---

14
15#include "cpld.hpp"
16
17#include "commands.hpp"
18#include "errors.hpp"
19#include "handler.hpp"
20
21#include <cstring>
1// Copyright 2021 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//

--- 5 unchanged lines hidden (view full) ---

14
15#include "cpld.hpp"
16
17#include "commands.hpp"
18#include "errors.hpp"
19#include "handler.hpp"
20
21#include <cstring>
22#include <ipmid/api-types.hpp>
23#include <vector>
22
23namespace google
24{
25namespace ipmi
26{
27
28struct CpldRequest
29{
24
25namespace google
26{
27namespace ipmi
28{
29
30struct CpldRequest
31{
30 uint8_t subcommand;
31 uint8_t id;
32} __attribute__((packed));
33
32 uint8_t id;
33} __attribute__((packed));
34
34struct CpldReply
35{
36 uint8_t subcommand;
37 uint8_t major;
38 uint8_t minor;
39 uint8_t point;
40 uint8_t subpoint;
41} __attribute__((packed));
42
43//
44// Handle reading the cpld version from the tmpfs.
45//
35//
36// Handle reading the cpld version from the tmpfs.
37//
46ipmi_ret_t cpldVersion(const uint8_t* reqBuf, uint8_t* replyBuf,
47 size_t* dataLen, const HandlerInterface* handler)
38Resp cpldVersion(const std::vector<std::uint8_t>& data,
39 const HandlerInterface* handler)
48{
49 struct CpldRequest request;
50
40{
41 struct CpldRequest request;
42
51 if ((*dataLen) < sizeof(request))
43 if (data.size() < sizeof(request))
52 {
53 std::fprintf(stderr, "Invalid command length: %u\n",
44 {
45 std::fprintf(stderr, "Invalid command length: %u\n",
54 static_cast<uint32_t>(*dataLen));
55 return IPMI_CC_REQ_DATA_LEN_INVALID;
46 static_cast<uint32_t>(data.size()));
47 return ::ipmi::responseReqDataLenInvalid();
56 }
57
48 }
49
58 // reqBuf[0] is the subcommand.
59 // reqBuf[1] is the CPLD id. "/run/cpld{id}.version" is what we read.
50 // data[0] is the CPLD id. "/run/cpld{id}.version" is what we read.
60 // Verified that this cast actually returns the value 255 and not something
51 // Verified that this cast actually returns the value 255 and not something
61 // negative in the case where reqBuf[1] is 0xff. However, it looks weird
52 // negative in the case where data[0] is 0xff. However, it looks weird
62 // since I would expect int(uint8(0xff)) to be -1. So, just cast it
63 // unsigned. we're casting to an int width to avoid it thinking it's a
64 // letter, because it does that.
53 // since I would expect int(uint8(0xff)) to be -1. So, just cast it
54 // unsigned. we're casting to an int width to avoid it thinking it's a
55 // letter, because it does that.
65 std::memcpy(&request, &reqBuf[0], sizeof(request));
56 std::memcpy(&request, data.data(), sizeof(request));
66
67 try
68 {
69 auto values =
70 handler->getCpldVersion(static_cast<unsigned int>(request.id));
71
72 // Truncate if the version is too high (documented).
57
58 try
59 {
60 auto values =
61 handler->getCpldVersion(static_cast<unsigned int>(request.id));
62
63 // Truncate if the version is too high (documented).
73 struct CpldReply reply;
74 reply.subcommand = SysCpldVersion;
75 reply.major = std::get<0>(values);
76 reply.minor = std::get<1>(values);
77 reply.point = std::get<2>(values);
78 reply.subpoint = std::get<3>(values);
64 auto major = std::get<0>(values);
65 auto minor = std::get<1>(values);
66 auto point = std::get<2>(values);
67 auto subpoint = std::get<3>(values);
79
68
80 std::memcpy(&replyBuf[0], &reply, sizeof(reply));
81 (*dataLen) = sizeof(reply);
82 return IPMI_CC_OK;
69 return ::ipmi::responseSuccess(
70 SysOEMCommands::SysCpldVersion,
71 std::vector<std::uint8_t>{major, minor, point, subpoint});
83 }
84 catch (const IpmiException& e)
85 {
72 }
73 catch (const IpmiException& e)
74 {
86 return e.getIpmiError();
75 return ::ipmi::response(e.getIpmiError());
87 }
88}
89
90} // namespace ipmi
91} // namespace google
76 }
77}
78
79} // namespace ipmi
80} // namespace google