xref: /openbmc/pldm/pldmtool/pldm_cmd_helper.hpp (revision 72512e61adc2f417eaabb06c7851367a3eee202c)
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