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