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, 33 sizeof(pldm_msg_hdr) + sizeof(effecterId) + 34 sizeof(effecterCount) + 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( 43 "Failed to encode set state effecter states request, response code '{RC}'", 44 "RC", lg2::hex, rc); 45 return -1; 46 } 47 48 PldmTransport pldmTransport{}; 49 50 // Create event loop and add a callback to handle EPOLLIN on fd 51 auto event = Event::get_default(); 52 auto callback = [=, 53 &pldmTransport](IO& io, int fd, uint32_t revents) mutable { 54 if (!(revents & EPOLLIN)) 55 { 56 return; 57 } 58 59 if (pldmTransport.getEventSource() != fd) 60 { 61 return; 62 } 63 64 void* responseMsg = nullptr; 65 size_t responseMsgSize{}; 66 pldm_tid_t srcTid; 67 auto rc = pldmTransport.recvMsg(srcTid, responseMsg, responseMsgSize); 68 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg); 69 if (rc || dstTid != srcTid || 70 !pldm_msg_hdr_correlate_response(&request->hdr, &response->hdr)) 71 { 72 return; 73 } 74 75 // We've got the response meant for the PLDM request msg that was sent 76 // out 77 io.set_enabled(Enabled::Off); 78 info( 79 "Done! Got the response for PLDM request message, response code '{RC}'", 80 "RC", lg2::hex, response->payload[0]); 81 free(responseMsg); 82 exit(EXIT_SUCCESS); 83 }; 84 IO io(event, pldmTransport.getEventSource(), EPOLLIN, std::move(callback)); 85 86 rc = pldmTransport.sendMsg(dstTid, requestMsg.data(), requestMsg.size()); 87 if (0 > rc) 88 { 89 error( 90 "Failed to send message/receive response, response code '{RC}' and error - {ERROR}", 91 "RC", rc, "ERROR", errno); 92 return -1; 93 } 94 95 event.loop(); 96 97 return 0; 98 } 99