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 << "\n"; 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" 47 << "\n"; 48 return -1; 49 } 50 51 // Create event loop and add a callback to handle EPOLLIN on fd 52 auto event = Event::get_default(); 53 auto callback = [=](IO& io, int fd, uint32_t revents) { 54 if (!(revents & EPOLLIN)) 55 { 56 return; 57 } 58 59 uint8_t* responseMsg = nullptr; 60 size_t responseMsgSize{}; 61 auto rc = pldm_recv(mctpEid, fd, request->hdr.instance_id, &responseMsg, 62 &responseMsgSize); 63 if (!rc) 64 { 65 // We've got the response meant for the PLDM request msg that was 66 // sent out 67 io.set_enabled(Enabled::Off); 68 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg); 69 std::cout << "Done. PLDM RC = " << std::hex << std::showbase 70 << static_cast<uint16_t>(response->payload[0]) 71 << std::endl; 72 free(responseMsg); 73 exit(EXIT_SUCCESS); 74 } 75 }; 76 IO io(event, fd, EPOLLIN, std::move(callback)); 77 78 // Send PLDM Request message - pldm_send doesn't wait for response 79 rc = pldm_send(mctpEid, fd, requestMsg.data(), requestMsg.size()); 80 if (0 > rc) 81 { 82 std::cerr << "Failed to send message/receive response. RC = " << rc 83 << ", errno = " << errno << "\n"; 84 return -1; 85 } 86 87 event.loop(); 88 89 return 0; 90 } 91