1 #include "libpldm/base.h" 2 #include "libpldm/platform.h" 3 #include "libpldm/requester/pldm.h" 4 5 #include <CLI/CLI.hpp> 6 #include <sdeventplus/event.hpp> 7 #include <sdeventplus/source/io.hpp> 8 9 #include <array> 10 #include <iostream> 11 12 using namespace sdeventplus; 13 using namespace sdeventplus::source; 14 15 int main(int argc, char** argv) 16 { 17 CLI::App app{"Send PLDM command SetStateEffecterStates"}; 18 uint8_t mctpEid{}; 19 app.add_option("-m,--mctp_eid", mctpEid, "MCTP EID")->required(); 20 uint16_t effecterId{}; 21 app.add_option("-e,--effecter", effecterId, "Effecter Id")->required(); 22 uint8_t state{}; 23 app.add_option("-s,--state", state, "New state value")->required(); 24 CLI11_PARSE(app, argc, argv); 25 26 // Encode PLDM Request message 27 uint8_t effecterCount = 1; 28 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + 29 sizeof(effecterCount) + 30 sizeof(set_effecter_state_field)> 31 requestMsg{}; 32 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 33 set_effecter_state_field stateField{PLDM_REQUEST_SET, state}; 34 auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount, 35 &stateField, request); 36 if (rc != PLDM_SUCCESS) 37 { 38 std::cerr << "Message encode failure. PLDM error code = " << std::hex 39 << std::showbase << rc << "\n"; 40 return -1; 41 } 42 43 // Get fd of MCTP socket 44 int fd = pldm_open(); 45 if (-1 == fd) 46 { 47 std::cerr << "Failed to init mctp" 48 << "\n"; 49 return -1; 50 } 51 52 // Create event loop and add a callback to handle EPOLLIN on fd 53 auto event = Event::get_default(); 54 auto callback = [=](IO& io, int fd, uint32_t revents) { 55 if (!(revents & EPOLLIN)) 56 { 57 return; 58 } 59 60 uint8_t* responseMsg = nullptr; 61 size_t responseMsgSize{}; 62 auto rc = pldm_recv(mctpEid, fd, request->hdr.instance_id, &responseMsg, 63 &responseMsgSize); 64 if (!rc) 65 { 66 // We've got the response meant for the PLDM request msg that was 67 // sent out 68 io.set_enabled(Enabled::Off); 69 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg); 70 std::cout << "Done. PLDM RC = " << std::hex << std::showbase 71 << static_cast<uint16_t>(response->payload[0]) 72 << std::endl; 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 std::cerr << "Failed to send message/receive response. RC = " << rc 84 << ", errno = " << errno << "\n"; 85 return -1; 86 } 87 88 event.loop(); 89 90 return 0; 91 } 92