19d494bbeSDeepak Kodihalli #include "libpldm/base.h"
29d494bbeSDeepak Kodihalli #include "libpldm/platform.h"
39d494bbeSDeepak Kodihalli #include "libpldm/requester/pldm.h"
49d494bbeSDeepak Kodihalli 
56492f524SGeorge Liu #include <CLI/CLI.hpp>
66492f524SGeorge Liu #include <sdeventplus/event.hpp>
76492f524SGeorge Liu #include <sdeventplus/source/io.hpp>
86492f524SGeorge Liu 
96492f524SGeorge Liu #include <array>
106492f524SGeorge Liu #include <iostream>
116492f524SGeorge Liu 
129d494bbeSDeepak Kodihalli using namespace sdeventplus;
139d494bbeSDeepak Kodihalli using namespace sdeventplus::source;
149d494bbeSDeepak Kodihalli 
159d494bbeSDeepak Kodihalli int main(int argc, char** argv)
169d494bbeSDeepak Kodihalli {
179d494bbeSDeepak Kodihalli     CLI::App app{"Send PLDM command SetStateEffecterStates"};
189d494bbeSDeepak Kodihalli     uint8_t mctpEid{};
199d494bbeSDeepak Kodihalli     app.add_option("-m,--mctp_eid", mctpEid, "MCTP EID")->required();
209d494bbeSDeepak Kodihalli     uint16_t effecterId{};
219d494bbeSDeepak Kodihalli     app.add_option("-e,--effecter", effecterId, "Effecter Id")->required();
229d494bbeSDeepak Kodihalli     uint8_t state{};
239d494bbeSDeepak Kodihalli     app.add_option("-s,--state", state, "New state value")->required();
249d494bbeSDeepak Kodihalli     CLI11_PARSE(app, argc, argv);
259d494bbeSDeepak Kodihalli 
269d494bbeSDeepak Kodihalli     // Encode PLDM Request message
279d494bbeSDeepak Kodihalli     uint8_t effecterCount = 1;
289d494bbeSDeepak Kodihalli     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) +
299d494bbeSDeepak Kodihalli                             sizeof(effecterCount) +
309d494bbeSDeepak Kodihalli                             sizeof(set_effecter_state_field)>
319d494bbeSDeepak Kodihalli         requestMsg{};
329d494bbeSDeepak Kodihalli     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
339d494bbeSDeepak Kodihalli     set_effecter_state_field stateField{PLDM_REQUEST_SET, state};
349d494bbeSDeepak Kodihalli     auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount,
359d494bbeSDeepak Kodihalli                                                    &stateField, request);
369d494bbeSDeepak Kodihalli     if (rc != PLDM_SUCCESS)
379d494bbeSDeepak Kodihalli     {
389d494bbeSDeepak Kodihalli         std::cerr << "Message encode failure. PLDM error code = " << std::hex
39aa8ae72fSSampa Misra                   << std::showbase << rc << "\n";
409d494bbeSDeepak Kodihalli         return -1;
419d494bbeSDeepak Kodihalli     }
429d494bbeSDeepak Kodihalli 
439d494bbeSDeepak Kodihalli     // Get fd of MCTP socket
449d494bbeSDeepak Kodihalli     int fd = pldm_open();
459d494bbeSDeepak Kodihalli     if (-1 == fd)
469d494bbeSDeepak Kodihalli     {
47aa8ae72fSSampa Misra         std::cerr << "Failed to init mctp"
48aa8ae72fSSampa Misra                   << "\n";
499d494bbeSDeepak Kodihalli         return -1;
509d494bbeSDeepak Kodihalli     }
519d494bbeSDeepak Kodihalli 
529d494bbeSDeepak Kodihalli     // Create event loop and add a callback to handle EPOLLIN on fd
539d494bbeSDeepak Kodihalli     auto event = Event::get_default();
549d494bbeSDeepak Kodihalli     auto callback = [=](IO& io, int fd, uint32_t revents) {
559d494bbeSDeepak Kodihalli         if (!(revents & EPOLLIN))
569d494bbeSDeepak Kodihalli         {
579d494bbeSDeepak Kodihalli             return;
589d494bbeSDeepak Kodihalli         }
599d494bbeSDeepak Kodihalli 
609d494bbeSDeepak Kodihalli         uint8_t* responseMsg = nullptr;
619d494bbeSDeepak Kodihalli         size_t responseMsgSize{};
629d494bbeSDeepak Kodihalli         auto rc = pldm_recv(mctpEid, fd, request->hdr.instance_id, &responseMsg,
639d494bbeSDeepak Kodihalli                             &responseMsgSize);
649d494bbeSDeepak Kodihalli         if (!rc)
659d494bbeSDeepak Kodihalli         {
669d494bbeSDeepak Kodihalli             // We've got the response meant for the PLDM request msg that was
679d494bbeSDeepak Kodihalli             // sent out
689d494bbeSDeepak Kodihalli             io.set_enabled(Enabled::Off);
699d494bbeSDeepak Kodihalli             pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg);
709d494bbeSDeepak Kodihalli             std::cout << "Done. PLDM RC = " << std::hex << std::showbase
719d494bbeSDeepak Kodihalli                       << static_cast<uint16_t>(response->payload[0])
729d494bbeSDeepak Kodihalli                       << std::endl;
739d494bbeSDeepak Kodihalli             free(responseMsg);
749d494bbeSDeepak Kodihalli             exit(EXIT_SUCCESS);
759d494bbeSDeepak Kodihalli         }
769d494bbeSDeepak Kodihalli     };
779d494bbeSDeepak Kodihalli     IO io(event, fd, EPOLLIN, std::move(callback));
789d494bbeSDeepak Kodihalli 
799d494bbeSDeepak Kodihalli     // Send PLDM Request message - pldm_send doesn't wait for response
809d494bbeSDeepak Kodihalli     rc = pldm_send(mctpEid, fd, requestMsg.data(), requestMsg.size());
81*9f8d2b0aSSampa Misra     if (0 > rc)
829d494bbeSDeepak Kodihalli     {
839d494bbeSDeepak Kodihalli         std::cerr << "Failed to send message/receive response. RC = " << rc
84aa8ae72fSSampa Misra                   << ", errno = " << errno << "\n";
859d494bbeSDeepak Kodihalli         return -1;
869d494bbeSDeepak Kodihalli     }
879d494bbeSDeepak Kodihalli 
889d494bbeSDeepak Kodihalli     event.loop();
899d494bbeSDeepak Kodihalli 
909d494bbeSDeepak Kodihalli     return 0;
919d494bbeSDeepak Kodihalli }
92