1 #include <commandutils.hpp>
2 #include <groupextcommands.hpp>
3 #include <ipmid/api-types.hpp>
4 #include <ipmid/api.hpp>
5 #include <phosphor-logging/lg2.hpp>
6
7 namespace ipmi
8 {
9
10 PHOSPHOR_LOG2_USING;
11
bigEndianToHost(uint64_t bigEndianValue)12 uint64_t bigEndianToHost(uint64_t bigEndianValue)
13 {
14 if (std::endian::native == std::endian::little)
15 {
16 return std::byteswap(bigEndianValue);
17 }
18
19 return bigEndianValue;
20 }
21
22 void registerSBMRFunctions() __attribute__((constructor));
23
ipmiSBMRSendBootProgress(ipmi::Context::ptr ctx,std::vector<uint8_t> data)24 ipmi::RspType<> ipmiSBMRSendBootProgress(ipmi::Context::ptr ctx,
25 std::vector<uint8_t> data)
26 {
27 using postcode_t = std::tuple<uint64_t, std::vector<uint8_t>>;
28
29 std::optional<size_t> hostId = findHost(ctx->hostIdx);
30
31 if (!hostId)
32 {
33 error("Invalid Host Id received");
34 return ipmi::responseInvalidCommand();
35 }
36
37 if (data.size() != 9)
38 {
39 error("Invalid request of boot progress length received: {LENGTH}",
40 "LENGTH", data.size());
41 return ipmi::responseReqDataLenInvalid();
42 }
43
44 try
45 {
46 auto primaryPostCode = reinterpret_cast<const uint64_t*>(data.data());
47 auto secondaryPostCode =
48 std::vector<uint8_t>(data.begin() + 8, data.end());
49 auto postCode =
50 postcode_t(bigEndianToHost(*primaryPostCode), secondaryPostCode);
51 auto conn = getSdBus();
52 auto hostbootRawObj =
53 std::string(bootRawObjPrefix) + std::to_string(*hostId);
54 auto method =
55 conn->new_method_call(bootRawBusName, hostbootRawObj.data(),
56 "org.freedesktop.DBus.Properties", "Set");
57
58 method.append(bootRawIntf, "Value", std::variant<postcode_t>(postCode));
59
60 conn->call_noreply(method);
61 }
62 catch (std::exception& e)
63 {
64 error("postcode handler error: {ERROR}", "ERROR", e);
65 return ipmi::responseResponseError();
66 }
67
68 return ipmi::responseSuccess();
69 }
70
registerSBMRFunctions()71 void registerSBMRFunctions()
72 {
73 ipmi::registerGroupHandler(
74 ipmi::prioOemBase, ipmi::groupSBMR, ipmi::sbmr::cmdSendBootProgress,
75 ipmi::Privilege::Admin, ipmiSBMRSendBootProgress);
76 return;
77 }
78
79 } // end of namespace ipmi
80