blob: eea275932180019820cc4a3524ced53177a6b510 [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_cmd_helper.hpp"
2
3constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
4constexpr uint8_t PLDM_ENTITY_ID = 8;
5
6using namespace std;
7
8/*
9 * print the input buffer
10 *
11 */
12void printBuffer(const std::vector<uint8_t>& buffer)
13{
14 std::ostringstream tempStream;
15 if (!buffer.empty())
16 {
17 for (int byte : buffer)
18 {
19 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
20 << " ";
21 }
22 }
23 cout << tempStream.str().c_str() << endl;
24}
25
26/*
27 * Initialize the socket, send pldm command & recieve response from socket
28 *
29 */
30int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
31 std::vector<uint8_t>& responseMsg)
32{
33 const char devPath[] = "\0mctp-mux";
34 int returnCode = 0;
35
36 int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
37 if (-1 == sockFd)
38 {
39 returnCode = -errno;
40 cerr << "Failed to create the socket : RC = " << sockFd << endl;
41 return returnCode;
42 }
43 cout << "Success in creating the socket : RC = " << sockFd << endl;
44
45 struct sockaddr_un addr
46 {
47 };
48 addr.sun_family = AF_UNIX;
49
50 memcpy(addr.sun_path, devPath, sizeof(devPath) - 1);
51
52 CustomFD socketFd(sockFd);
53 int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr),
54 sizeof(devPath) + sizeof(addr.sun_family) - 1);
55 if (-1 == result)
56 {
57 returnCode = -errno;
58 cerr << "Failed to connect to socket : RC = " << returnCode << endl;
59 return returnCode;
60 }
61 cout << "Success in connecting to socket : RC = " << returnCode << endl;
62
63 auto pldmType = MCTP_MSG_TYPE_PLDM;
64 result = write(socketFd(), &pldmType, sizeof(pldmType));
65 if (-1 == result)
66 {
67 returnCode = -errno;
68 cerr << "Failed to send message type as pldm to mctp : RC = "
69 << returnCode << endl;
70 return returnCode;
71 }
72 cout << "Success in sending message type as pldm to mctp : RC = "
73 << returnCode << endl;
74
75 result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0);
76 if (-1 == result)
77 {
78 returnCode = -errno;
79 cerr << "Write to socket failure : RC = " << returnCode << endl;
80 return returnCode;
81 }
82 cout << "Write to socket successful : RC = " << result << endl;
83
84 // Read the response from socket
85 ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK);
86 if (0 == peekedLength)
87 {
88 cerr << "Socket is closed : peekedLength = " << peekedLength << endl;
89 return returnCode;
90 }
91 else if (peekedLength <= -1)
92 {
93 returnCode = -errno;
94 cerr << "recv() system call failed : RC = " << returnCode << endl;
95 return returnCode;
96 }
97 else
98 {
99 // loopback response message
100 std::vector<uint8_t> loopBackRespMsg(peekedLength);
101 auto recvDataLength =
102 recv(socketFd(), reinterpret_cast<void*>(loopBackRespMsg.data()),
103 peekedLength, 0);
104 if (recvDataLength == peekedLength)
105 {
106 cout << "Total length:" << recvDataLength << endl;
107 cout << "Loopback response message:" << endl;
108 printBuffer(loopBackRespMsg);
109 }
110 else
111 {
112 cerr << "Failure to read peeked length packet : RC = " << returnCode
113 << endl;
114 cerr << "peekedLength: " << peekedLength << endl;
115 cerr << "Total length: " << recvDataLength << endl;
116 return returnCode;
117 }
118
119 // Confirming on the first recv() the Request bit is set in
120 // pldm_msg_hdr struct. If set proceed with recv() or else, quit.
121 auto hdr = reinterpret_cast<const pldm_msg_hdr*>(&loopBackRespMsg[2]);
122 uint8_t request = hdr->request;
123 if (request == PLDM_REQUEST)
124 {
125 cout << "On first recv(),response == request : RC = " << returnCode
126 << endl;
127 ssize_t peekedLength =
128 recv(socketFd(), nullptr, 0, MSG_PEEK | MSG_TRUNC);
129
130 responseMsg.resize(peekedLength);
131 recvDataLength =
132 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
133 peekedLength, 0);
134 if (recvDataLength == peekedLength)
135 {
136 cout << "Total length: " << recvDataLength << endl;
137 }
138 else
139 {
140 cerr << "Failure to read response length packet: length = "
141 << recvDataLength << endl;
142 return returnCode;
143 }
144 }
145 else
146 {
147 cerr << "On first recv(),request != response : RC = " << returnCode
148 << endl;
149 return returnCode;
150 }
151 }
152 returnCode = shutdown(socketFd(), SHUT_RDWR);
153 if (-1 == returnCode)
154 {
155 returnCode = -errno;
156 cerr << "Failed to shutdown the socket : RC = " << returnCode << endl;
157 return returnCode;
158 }
159
160 cout << "Shutdown Socket successful : RC = " << returnCode << endl;
161 return PLDM_SUCCESS;
162}