1 #include "common/transport.hpp" 2 3 #include <libpldm/base.h> 4 #include <libpldm/platform.h> 5 6 #include <CLI/CLI.hpp> 7 #include <phosphor-logging/lg2.hpp> 8 #include <sdeventplus/event.hpp> 9 #include <sdeventplus/source/io.hpp> 10 11 #include <array> 12 13 using namespace sdeventplus; 14 using namespace sdeventplus::source; 15 PHOSPHOR_LOG2_USING; 16 17 int main(int argc, char** argv) 18 { 19 CLI::App app{"Send PLDM command SetStateEffecterStates"}; 20 uint8_t mctpEid{}; 21 app.add_option("-m,--mctp_eid", mctpEid, "MCTP EID")->required(); 22 uint16_t effecterId{}; 23 app.add_option("-e,--effecter", effecterId, "Effecter Id")->required(); 24 uint8_t state{}; 25 app.add_option("-s,--state", state, "New state value")->required(); 26 CLI11_PARSE(app, argc, argv); 27 28 pldm_tid_t dstTid = static_cast<pldm_tid_t>(mctpEid); 29 30 // Encode PLDM Request message 31 uint8_t effecterCount = 1; 32 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + 33 sizeof(effecterCount) + 34 sizeof(set_effecter_state_field)> 35 requestMsg{}; 36 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 37 set_effecter_state_field stateField{PLDM_REQUEST_SET, state}; 38 auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount, 39 &stateField, request); 40 if (rc != PLDM_SUCCESS) 41 { 42 error("Message encode failure. PLDM error code = {RC}", "RC", lg2::hex, 43 rc); 44 return -1; 45 } 46 47 PldmTransport pldmTransport{}; 48 49 // Create event loop and add a callback to handle EPOLLIN on fd 50 auto event = Event::get_default(); 51 auto callback = [=, &pldmTransport](IO& io, int fd, 52 uint32_t revents) mutable { 53 if (!(revents & EPOLLIN)) 54 { 55 return; 56 } 57 58 if (pldmTransport.getEventSource() != fd) 59 { 60 return; 61 } 62 63 void* responseMsg = nullptr; 64 size_t responseMsgSize{}; 65 pldm_tid_t srcTid; 66 auto rc = pldmTransport.recvMsg(srcTid, responseMsg, responseMsgSize); 67 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg); 68 if (rc || dstTid != srcTid || 69 !pldm_msg_hdr_correlate_response(&request->hdr, &response->hdr)) 70 { 71 return; 72 } 73 74 // We've got the response meant for the PLDM request msg that was sent 75 // out 76 io.set_enabled(Enabled::Off); 77 info("Done. PLDM RC = {RC}", "RC", lg2::hex, 78 static_cast<uint16_t>(response->payload[0])); 79 free(responseMsg); 80 exit(EXIT_SUCCESS); 81 }; 82 IO io(event, pldmTransport.getEventSource(), EPOLLIN, std::move(callback)); 83 84 rc = pldmTransport.sendMsg(dstTid, requestMsg.data(), requestMsg.size()); 85 if (0 > rc) 86 { 87 error( 88 "Failed to send message/receive response. RC = {RC} errno = {ERR}", 89 "RC", rc, "ERR", errno); 90 return -1; 91 } 92 93 event.loop(); 94 95 return 0; 96 } 97