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 #include <iostream> 13 14 using namespace sdeventplus; 15 using namespace sdeventplus::source; 16 PHOSPHOR_LOG2_USING; 17 18 int main(int argc, char** argv) 19 { 20 CLI::App app{"Send PLDM command SetStateEffecterStates"}; 21 uint8_t mctpEid{}; 22 app.add_option("-m,--mctp_eid", mctpEid, "MCTP EID")->required(); 23 uint16_t effecterId{}; 24 app.add_option("-e,--effecter", effecterId, "Effecter Id")->required(); 25 uint8_t state{}; 26 app.add_option("-s,--state", state, "New state value")->required(); 27 CLI11_PARSE(app, argc, argv); 28 29 pldm_tid_t dstTid = static_cast<pldm_tid_t>(mctpEid); 30 31 // Encode PLDM Request message 32 uint8_t effecterCount = 1; 33 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + 34 sizeof(effecterCount) + 35 sizeof(set_effecter_state_field)> 36 requestMsg{}; 37 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 38 set_effecter_state_field stateField{PLDM_REQUEST_SET, state}; 39 auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount, 40 &stateField, request); 41 if (rc != PLDM_SUCCESS) 42 { 43 error("Message encode failure. PLDM error code = {RC}", "RC", lg2::hex, 44 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 = [=, &pldmTransport](IO& io, int fd, 53 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("Done. PLDM RC = {RC}", "RC", lg2::hex, 79 static_cast<uint16_t>(response->payload[0])); 80 free(responseMsg); 81 exit(EXIT_SUCCESS); 82 }; 83 IO io(event, pldmTransport.getEventSource(), EPOLLIN, std::move(callback)); 84 85 rc = pldmTransport.sendMsg(dstTid, requestMsg.data(), requestMsg.size()); 86 if (0 > rc) 87 { 88 error( 89 "Failed to send message/receive response. RC = {RC} errno = {ERR}", 90 "RC", rc, "ERR", errno); 91 return -1; 92 } 93 94 event.loop(); 95 96 return 0; 97 } 98