blob: 5e8658f85490140c55079090bf26db1dcc45aeb8 [file] [log] [blame]
Ravi Tejace1c96f2020-10-05 23:13:01 -05001#include "utils.hpp"
2
Sampa Misra245fc6f2021-08-12 10:30:34 -05003#include "common/utils.hpp"
4
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/base.h>
Ravi Tejace1c96f2020-10-05 23:13:01 -05006#include <sys/socket.h>
7#include <sys/types.h>
8#include <sys/un.h>
9#include <unistd.h>
10
Riya Dixit49cfb132023-03-02 04:26:53 -060011#include <phosphor-logging/lg2.hpp>
Sampa Misra245fc6f2021-08-12 10:30:34 -050012#include <xyz/openbmc_project/Inventory/Decorator/Asset/client.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060013
Riya Dixit49cfb132023-03-02 04:26:53 -060014PHOSPHOR_LOG2_USING;
15
Ravi Tejace1c96f2020-10-05 23:13:01 -050016namespace pldm
17{
18namespace responder
19{
20namespace utils
21{
Ravi Tejace1c96f2020-10-05 23:13:01 -050022int setupUnixSocket(const std::string& socketInterface)
23{
24 int sock;
25 struct sockaddr_un addr;
26 memset(&addr, 0, sizeof(addr));
27 addr.sun_family = AF_UNIX;
28 if (strnlen(socketInterface.c_str(), sizeof(addr.sun_path)) ==
29 sizeof(addr.sun_path))
30 {
Riya Dixit49cfb132023-03-02 04:26:53 -060031 error("setupUnixSocket: UNIX socket path too long");
Ravi Tejace1c96f2020-10-05 23:13:01 -050032 return -1;
33 }
34
35 strncpy(addr.sun_path, socketInterface.c_str(), sizeof(addr.sun_path) - 1);
36
37 if ((sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
38 {
Riya Dixit49cfb132023-03-02 04:26:53 -060039 error("setupUnixSocket: socket() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050040 return -1;
41 }
42
43 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
44 {
Riya Dixit49cfb132023-03-02 04:26:53 -060045 error("setupUnixSocket: bind() call failed with errno {ERR}", "ERR",
46 errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050047 close(sock);
48 return -1;
49 }
50
51 if (listen(sock, 1) == -1)
52 {
Riya Dixit49cfb132023-03-02 04:26:53 -060053 error("setupUnixSocket: listen() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050054 close(sock);
55 return -1;
56 }
57
58 fd_set rfd;
59 struct timeval tv;
60 tv.tv_sec = 1;
61 tv.tv_usec = 0;
62
63 FD_ZERO(&rfd);
64 FD_SET(sock, &rfd);
65 int nfd = sock + 1;
Andrew Geisslerefbb5942020-12-15 10:12:30 -060066 int fd = -1;
Ravi Tejace1c96f2020-10-05 23:13:01 -050067
68 int retval = select(nfd, &rfd, NULL, NULL, &tv);
69 if (retval < 0)
70 {
Riya Dixit49cfb132023-03-02 04:26:53 -060071 error("setupUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050072 close(sock);
73 return -1;
74 }
75
76 if ((retval > 0) && (FD_ISSET(sock, &rfd)))
77 {
78 fd = accept(sock, NULL, NULL);
79 if (fd < 0)
80 {
Riya Dixit49cfb132023-03-02 04:26:53 -060081 error("setupUnixSocket: accept() call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050082 close(sock);
83 return -1;
84 }
85 close(sock);
86 }
87 return fd;
88}
89
90int writeToUnixSocket(const int sock, const char* buf, const uint64_t blockSize)
91{
92 uint64_t i;
93 int nwrite = 0;
94
95 for (i = 0; i < blockSize; i = i + nwrite)
96 {
Ravi Tejace1c96f2020-10-05 23:13:01 -050097 fd_set wfd;
98 struct timeval tv;
99 tv.tv_sec = 1;
100 tv.tv_usec = 0;
101
102 FD_ZERO(&wfd);
103 FD_SET(sock, &wfd);
104 int nfd = sock + 1;
105
106 int retval = select(nfd, NULL, &wfd, NULL, &tv);
107 if (retval < 0)
108 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600109 error("writeToUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500110 close(sock);
111 return -1;
112 }
113 if (retval == 0)
114 {
115 nwrite = 0;
116 continue;
117 }
118 if ((retval > 0) && (FD_ISSET(sock, &wfd)))
119 {
120 nwrite = write(sock, buf + i, blockSize - i);
121 if (nwrite < 0)
122 {
123 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
124 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600125 error(
126 "writeToUnixSocket: Write call failed with EAGAIN or EWOULDBLOCK or EINTR");
Ravi Tejace1c96f2020-10-05 23:13:01 -0500127 nwrite = 0;
128 continue;
129 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600130 error("writeToUnixSocket: Failed to write {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500131 close(sock);
132 return -1;
133 }
134 }
135 else
136 {
137 nwrite = 0;
138 }
139 }
140 return 0;
141}
142
Sampa Misra245fc6f2021-08-12 10:30:34 -0500143bool checkIfIBMFru(const std::string& objPath)
144{
145 using DecoratorAsset =
146 sdbusplus::client::xyz::openbmc_project::inventory::decorator::Asset<>;
147
148 try
149 {
150 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
151 objPath.c_str(), "Model", DecoratorAsset::interface);
152 const auto& model = std::get<std::string>(propVal);
153 if (!model.empty())
154 {
155 return true;
156 }
157 }
158 catch (const std::exception&)
159 {
160 return false;
161 }
162 return false;
163}
164
Ravi Tejace1c96f2020-10-05 23:13:01 -0500165} // namespace utils
166} // namespace responder
167} // namespace pldm