11ed5f7a6SRashmica Gupta #include "common/transport.hpp"
21ed5f7a6SRashmica Gupta 
3c453e164SGeorge Liu #include <libpldm/base.h>
4c453e164SGeorge Liu #include <libpldm/platform.h>
59d494bbeSDeepak Kodihalli 
66492f524SGeorge Liu #include <CLI/CLI.hpp>
749cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
86492f524SGeorge Liu #include <sdeventplus/event.hpp>
96492f524SGeorge Liu #include <sdeventplus/source/io.hpp>
106492f524SGeorge Liu 
116492f524SGeorge Liu #include <array>
126492f524SGeorge Liu 
139d494bbeSDeepak Kodihalli using namespace sdeventplus;
149d494bbeSDeepak Kodihalli using namespace sdeventplus::source;
1549cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
169d494bbeSDeepak Kodihalli 
main(int argc,char ** argv)179d494bbeSDeepak Kodihalli int main(int argc, char** argv)
189d494bbeSDeepak Kodihalli {
199d494bbeSDeepak Kodihalli     CLI::App app{"Send PLDM command SetStateEffecterStates"};
209d494bbeSDeepak Kodihalli     uint8_t mctpEid{};
219d494bbeSDeepak Kodihalli     app.add_option("-m,--mctp_eid", mctpEid, "MCTP EID")->required();
229d494bbeSDeepak Kodihalli     uint16_t effecterId{};
239d494bbeSDeepak Kodihalli     app.add_option("-e,--effecter", effecterId, "Effecter Id")->required();
249d494bbeSDeepak Kodihalli     uint8_t state{};
259d494bbeSDeepak Kodihalli     app.add_option("-s,--state", state, "New state value")->required();
269d494bbeSDeepak Kodihalli     CLI11_PARSE(app, argc, argv);
279d494bbeSDeepak Kodihalli 
281ed5f7a6SRashmica Gupta     pldm_tid_t dstTid = static_cast<pldm_tid_t>(mctpEid);
291ed5f7a6SRashmica Gupta 
309d494bbeSDeepak Kodihalli     // Encode PLDM Request message
319d494bbeSDeepak Kodihalli     uint8_t effecterCount = 1;
329d494bbeSDeepak Kodihalli     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) +
339d494bbeSDeepak Kodihalli                             sizeof(effecterCount) +
349d494bbeSDeepak Kodihalli                             sizeof(set_effecter_state_field)>
359d494bbeSDeepak Kodihalli         requestMsg{};
369d494bbeSDeepak Kodihalli     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
379d494bbeSDeepak Kodihalli     set_effecter_state_field stateField{PLDM_REQUEST_SET, state};
389d494bbeSDeepak Kodihalli     auto rc = encode_set_state_effecter_states_req(0, effecterId, effecterCount,
399d494bbeSDeepak Kodihalli                                                    &stateField, request);
409d494bbeSDeepak Kodihalli     if (rc != PLDM_SUCCESS)
419d494bbeSDeepak Kodihalli     {
42087a751fSRiya Dixit         error(
43087a751fSRiya Dixit             "Failed to encode set state effecter states request, response code '{RC}'",
44087a751fSRiya Dixit             "RC", lg2::hex, rc);
459d494bbeSDeepak Kodihalli         return -1;
469d494bbeSDeepak Kodihalli     }
479d494bbeSDeepak Kodihalli 
481ed5f7a6SRashmica Gupta     PldmTransport pldmTransport{};
499d494bbeSDeepak Kodihalli 
509d494bbeSDeepak Kodihalli     // Create event loop and add a callback to handle EPOLLIN on fd
519d494bbeSDeepak Kodihalli     auto event = Event::get_default();
52a675662cSPatrick Williams     auto callback = [=, &pldmTransport](IO& io, int fd,
53a675662cSPatrick Williams                                         uint32_t revents) mutable {
549d494bbeSDeepak Kodihalli         if (!(revents & EPOLLIN))
559d494bbeSDeepak Kodihalli         {
569d494bbeSDeepak Kodihalli             return;
579d494bbeSDeepak Kodihalli         }
589d494bbeSDeepak Kodihalli 
591ed5f7a6SRashmica Gupta         if (pldmTransport.getEventSource() != fd)
609d494bbeSDeepak Kodihalli         {
611ed5f7a6SRashmica Gupta             return;
621ed5f7a6SRashmica Gupta         }
631ed5f7a6SRashmica Gupta 
641ed5f7a6SRashmica Gupta         void* responseMsg = nullptr;
651ed5f7a6SRashmica Gupta         size_t responseMsgSize{};
661ed5f7a6SRashmica Gupta         pldm_tid_t srcTid;
671ed5f7a6SRashmica Gupta         auto rc = pldmTransport.recvMsg(srcTid, responseMsg, responseMsgSize);
689d494bbeSDeepak Kodihalli         pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg);
691ed5f7a6SRashmica Gupta         if (rc || dstTid != srcTid ||
701ed5f7a6SRashmica Gupta             !pldm_msg_hdr_correlate_response(&request->hdr, &response->hdr))
711ed5f7a6SRashmica Gupta         {
721ed5f7a6SRashmica Gupta             return;
731ed5f7a6SRashmica Gupta         }
741ed5f7a6SRashmica Gupta 
751ed5f7a6SRashmica Gupta         // We've got the response meant for the PLDM request msg that was sent
761ed5f7a6SRashmica Gupta         // out
771ed5f7a6SRashmica Gupta         io.set_enabled(Enabled::Off);
78087a751fSRiya Dixit         info(
79087a751fSRiya Dixit             "Done! Got the response for PLDM request message, response code '{RC}'",
80*1e5c81e0SRiya Dixit             "RC", lg2::hex, response->payload[0]);
819d494bbeSDeepak Kodihalli         free(responseMsg);
829d494bbeSDeepak Kodihalli         exit(EXIT_SUCCESS);
839d494bbeSDeepak Kodihalli     };
841ed5f7a6SRashmica Gupta     IO io(event, pldmTransport.getEventSource(), EPOLLIN, std::move(callback));
859d494bbeSDeepak Kodihalli 
861ed5f7a6SRashmica Gupta     rc = pldmTransport.sendMsg(dstTid, requestMsg.data(), requestMsg.size());
879f8d2b0aSSampa Misra     if (0 > rc)
889d494bbeSDeepak Kodihalli     {
8949cfb138SRiya Dixit         error(
90087a751fSRiya Dixit             "Failed to send message/receive response, response code '{RC}' and error - {ERROR}",
91087a751fSRiya Dixit             "RC", rc, "ERROR", errno);
929d494bbeSDeepak Kodihalli         return -1;
939d494bbeSDeepak Kodihalli     }
949d494bbeSDeepak Kodihalli 
959d494bbeSDeepak Kodihalli     event.loop();
969d494bbeSDeepak Kodihalli 
979d494bbeSDeepak Kodihalli     return 0;
989d494bbeSDeepak Kodihalli }
99