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 
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 
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 postCode = postcode_t(bigEndianToHost(*primaryPostCode), data);
48         auto conn = getSdBus();
49         auto hostbootRawObj = std::string(bootRawObjPrefix) +
50                               std::to_string(*hostId);
51         auto method =
52             conn->new_method_call(bootRawBusName, hostbootRawObj.data(),
53                                   "org.freedesktop.DBus.Properties", "Set");
54 
55         method.append(bootRawIntf, "Value", std::variant<postcode_t>(postCode));
56 
57         conn->call_noreply(method);
58     }
59     catch (std::exception& e)
60     {
61         error("postcode handler error: {ERROR}", "ERROR", e);
62         return ipmi::responseResponseError();
63     }
64 
65     return ipmi::responseSuccess();
66 }
67 
68 void registerSBMRFunctions()
69 {
70     ipmi::registerGroupHandler(
71         ipmi::prioOemBase, ipmi::groupSBMR, ipmi::sbmr::cmdSendBootProgress,
72         ipmi::Privilege::Admin, ipmiSBMRSendBootProgress);
73     return;
74 }
75 
76 } // end of namespace ipmi
77