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