1 #pragma once
2
3 #include "common/instance_id.hpp"
4 #include "common/utils.hpp"
5
6 #include <err.h>
7 #include <libpldm/base.h>
8 #include <libpldm/bios.h>
9 #include <libpldm/fru.h>
10 #include <libpldm/platform.h>
11 #include <sys/socket.h>
12 #include <sys/un.h>
13 #include <unistd.h>
14
15 #include <CLI/CLI.hpp>
16 #include <nlohmann/json.hpp>
17
18 #include <cstring>
19 #include <iomanip>
20 #include <iostream>
21 #include <utility>
22
23 namespace pldmtool
24 {
25
26 namespace helper
27 {
28
29 constexpr uint8_t PLDM_ENTITY_ID = 8;
30 using ordered_json = nlohmann::ordered_json;
31
32 /** @brief print the input message if pldmverbose is enabled
33 *
34 * @param[in] pldmVerbose - verbosity flag - true/false
35 * @param[in] msg - message to print
36 * @param[in] data - data to print
37 *
38 * @return - None
39 */
40
41 template <class T>
Logger(bool pldmverbose,const char * msg,const T & data)42 void Logger(bool pldmverbose, const char* msg, const T& data)
43 {
44 if (pldmverbose)
45 {
46 std::stringstream s;
47 s << data;
48 std::cout << msg << s.str() << std::endl;
49 }
50 }
51
52 /** @brief Display in JSON format.
53 *
54 * @param[in] data - data to print in json
55 *
56 * @return - None
57 */
DisplayInJson(const ordered_json & data)58 static inline void DisplayInJson(const ordered_json& data)
59 {
60 std::cout << data.dump(4) << std::endl;
61 }
62
63 /**
64 * @brief Maps numeric PLDM completion codes to human-readable strings
65 *
66 * @param[in] completionCode - Numeric PLDM completion code returned in response
67 * @param[in] data - The JSON data to which the completion code is added.
68 * @param[in] pldmType - PLDM type
69 */
70 void fillCompletionCode(uint8_t completionCode, ordered_json& data,
71 uint8_t pldmType);
72
73 /** @brief MCTP socket read/receive
74 *
75 * @param[in] requestMsg - Request message to compare against loopback
76 * message received from mctp socket
77 * @param[out] responseMsg - Response buffer received from mctp socket
78 * @param[in] pldmVerbose - verbosity flag - true/false
79 *
80 * @return - 0 on success.
81 * -1 or -errno on failure.
82 */
83 int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
84 std::vector<uint8_t>& responseMsg, bool pldmVerbose);
85
86 class CommandInterface
87 {
88 public:
CommandInterface(const char * type,const char * name,CLI::App * app)89 explicit CommandInterface(const char* type, const char* name,
90 CLI::App* app) :
91 pldmType(type), commandName(name), mctp_eid(PLDM_ENTITY_ID),
92 pldmVerbose(false), instanceId(0)
93 {
94 app->add_option("-m,--mctp_eid", mctp_eid, "MCTP endpoint ID");
95 app->add_flag("-v, --verbose", pldmVerbose);
96 app->add_option("-n, --retry-count", numRetries,
97 "Number of retry when PLDM request message is failed");
98 app->callback([&]() { exec(); });
99 }
100
101 virtual ~CommandInterface() = default;
102
103 virtual std::pair<int, std::vector<uint8_t>> createRequestMsg() = 0;
104
105 virtual void parseResponseMsg(struct pldm_msg* responsePtr,
106 size_t payloadLength) = 0;
107
108 virtual void exec();
109
110 int pldmSendRecv(std::vector<uint8_t>& requestMsg,
111 std::vector<uint8_t>& responseMsg);
112
113 /**
114 * @brief get MCTP endpoint ID
115 *
116 * @return uint8_t - MCTP endpoint ID
117 */
getMCTPEID()118 inline uint8_t getMCTPEID()
119 {
120 return mctp_eid;
121 }
122
123 /**
124 * @brief get PLDM type
125 *
126 * @return pldm type
127 */
getPLDMType()128 inline std::string getPLDMType()
129 {
130 return pldmType;
131 }
132
133 /**
134 * @brief get command name
135 *
136 * @return the command name
137 */
getCommandName()138 inline std::string getCommandName()
139 {
140 return commandName;
141 }
142
143 private:
144 const std::string pldmType;
145 const std::string commandName;
146 uint8_t mctp_eid;
147 bool pldmVerbose;
148
149 protected:
150 uint8_t instanceId;
151 pldm::InstanceIdDb instanceIdDb;
152 uint8_t numRetries = 0;
153 };
154
155 } // namespace helper
156 } // namespace pldmtool
157