1 #include <libpldm/base.h> 2 #include <libpldm/platform.h> 3 #include <libpldm/pldm.h> 4 5 #include <CLI/CLI.hpp> 6 #include <phosphor-logging/lg2.hpp> 7 #include <sdeventplus/event.hpp> 8 #include <sdeventplus/source/io.hpp> 9 10 #include <array> 11 #include <iostream> 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 // Encode PLDM Request message 29 uint8_t effecterCount = 1; 30 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + 31 sizeof(effecterCount) + 32 sizeof(set_effecter_state_field)> 33 requestMsg{}; 34 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 35 set_effecter_state_field stateField{PLDM_REQUEST_SET, state}; 36 auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount, 37 &stateField, request); 38 if (rc != PLDM_SUCCESS) 39 { 40 error("Message encode failure. PLDM error code = {RC}", "RC", lg2::hex, 41 rc); 42 return -1; 43 } 44 45 // Get fd of MCTP socket 46 int fd = pldm_open(); 47 if (-1 == fd) 48 { 49 error("Failed to init mctp"); 50 return -1; 51 } 52 53 // Create event loop and add a callback to handle EPOLLIN on fd 54 auto event = Event::get_default(); 55 auto callback = [=](IO& io, int fd, uint32_t revents) { 56 if (!(revents & EPOLLIN)) 57 { 58 return; 59 } 60 61 uint8_t* responseMsg = nullptr; 62 size_t responseMsgSize{}; 63 auto rc = pldm_recv(mctpEid, fd, request->hdr.instance_id, &responseMsg, 64 &responseMsgSize); 65 if (!rc) 66 { 67 // We've got the response meant for the PLDM request msg that was 68 // sent out 69 io.set_enabled(Enabled::Off); 70 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg); 71 info("Done. PLDM RC = {RC}", "RC", lg2::hex, 72 static_cast<uint16_t>(response->payload[0])); 73 free(responseMsg); 74 exit(EXIT_SUCCESS); 75 } 76 }; 77 IO io(event, fd, EPOLLIN, std::move(callback)); 78 79 // Send PLDM Request message - pldm_send doesn't wait for response 80 rc = pldm_send(mctpEid, fd, requestMsg.data(), requestMsg.size()); 81 if (0 > rc) 82 { 83 error( 84 "Failed to send message/receive response. RC = {RC} errno = {ERR}", 85 "RC", rc, "ERR", errno); 86 return -1; 87 } 88 89 event.loop(); 90 91 return 0; 92 } 93