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