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