blob: 05978b46fb840d0c772b753b3854fb1b4c87fc45 [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>
Pavithra Barithaya9e0e8262024-04-15 09:12:16 -050013#include <xyz/openbmc_project/Inventory/Item/Connector/client.hpp>
14#include <xyz/openbmc_project/ObjectMapper/client.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060015
Riya Dixit49cfb132023-03-02 04:26:53 -060016PHOSPHOR_LOG2_USING;
17
Ravi Tejace1c96f2020-10-05 23:13:01 -050018namespace pldm
19{
20namespace responder
21{
22namespace utils
23{
Ravi Tejace1c96f2020-10-05 23:13:01 -050024int setupUnixSocket(const std::string& socketInterface)
25{
26 int sock;
27 struct sockaddr_un addr;
28 memset(&addr, 0, sizeof(addr));
29 addr.sun_family = AF_UNIX;
30 if (strnlen(socketInterface.c_str(), sizeof(addr.sun_path)) ==
31 sizeof(addr.sun_path))
32 {
Riya Dixit49cfb132023-03-02 04:26:53 -060033 error("setupUnixSocket: UNIX socket path too long");
Ravi Tejace1c96f2020-10-05 23:13:01 -050034 return -1;
35 }
36
37 strncpy(addr.sun_path, socketInterface.c_str(), sizeof(addr.sun_path) - 1);
38
39 if ((sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
40 {
Riya Dixit49cfb132023-03-02 04:26:53 -060041 error("setupUnixSocket: socket() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050042 return -1;
43 }
44
45 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
46 {
Riya Dixit49cfb132023-03-02 04:26:53 -060047 error("setupUnixSocket: bind() call failed with errno {ERR}", "ERR",
48 errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050049 close(sock);
50 return -1;
51 }
52
53 if (listen(sock, 1) == -1)
54 {
Riya Dixit49cfb132023-03-02 04:26:53 -060055 error("setupUnixSocket: listen() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050056 close(sock);
57 return -1;
58 }
59
60 fd_set rfd;
61 struct timeval tv;
62 tv.tv_sec = 1;
63 tv.tv_usec = 0;
64
65 FD_ZERO(&rfd);
66 FD_SET(sock, &rfd);
67 int nfd = sock + 1;
Andrew Geisslerefbb5942020-12-15 10:12:30 -060068 int fd = -1;
Ravi Tejace1c96f2020-10-05 23:13:01 -050069
70 int retval = select(nfd, &rfd, NULL, NULL, &tv);
71 if (retval < 0)
72 {
Riya Dixit49cfb132023-03-02 04:26:53 -060073 error("setupUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050074 close(sock);
75 return -1;
76 }
77
78 if ((retval > 0) && (FD_ISSET(sock, &rfd)))
79 {
80 fd = accept(sock, NULL, NULL);
81 if (fd < 0)
82 {
Riya Dixit49cfb132023-03-02 04:26:53 -060083 error("setupUnixSocket: accept() call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050084 close(sock);
85 return -1;
86 }
87 close(sock);
88 }
89 return fd;
90}
91
92int writeToUnixSocket(const int sock, const char* buf, const uint64_t blockSize)
93{
94 uint64_t i;
95 int nwrite = 0;
96
97 for (i = 0; i < blockSize; i = i + nwrite)
98 {
Ravi Tejace1c96f2020-10-05 23:13:01 -050099 fd_set wfd;
100 struct timeval tv;
101 tv.tv_sec = 1;
102 tv.tv_usec = 0;
103
104 FD_ZERO(&wfd);
105 FD_SET(sock, &wfd);
106 int nfd = sock + 1;
107
108 int retval = select(nfd, NULL, &wfd, NULL, &tv);
109 if (retval < 0)
110 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600111 error("writeToUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500112 close(sock);
113 return -1;
114 }
115 if (retval == 0)
116 {
117 nwrite = 0;
118 continue;
119 }
120 if ((retval > 0) && (FD_ISSET(sock, &wfd)))
121 {
122 nwrite = write(sock, buf + i, blockSize - i);
123 if (nwrite < 0)
124 {
125 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
126 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600127 error(
128 "writeToUnixSocket: Write call failed with EAGAIN or EWOULDBLOCK or EINTR");
Ravi Tejace1c96f2020-10-05 23:13:01 -0500129 nwrite = 0;
130 continue;
131 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600132 error("writeToUnixSocket: Failed to write {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500133 close(sock);
134 return -1;
135 }
136 }
137 else
138 {
139 nwrite = 0;
140 }
141 }
142 return 0;
143}
144
Sampa Misra245fc6f2021-08-12 10:30:34 -0500145bool checkIfIBMFru(const std::string& objPath)
146{
147 using DecoratorAsset =
148 sdbusplus::client::xyz::openbmc_project::inventory::decorator::Asset<>;
149
150 try
151 {
152 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
153 objPath.c_str(), "Model", DecoratorAsset::interface);
154 const auto& model = std::get<std::string>(propVal);
155 if (!model.empty())
156 {
157 return true;
158 }
159 }
160 catch (const std::exception&)
161 {
162 return false;
163 }
164 return false;
165}
166
Pavithra Barithaya9e0e8262024-04-15 09:12:16 -0500167std::vector<std::string> findPortObjects(const std::string& adapterObjPath)
168{
169 using ItemConnector =
170 sdbusplus::client::xyz::openbmc_project::inventory::item::Connector<>;
171
172 std::vector<std::string> portObjects;
173 try
174 {
175 portObjects = pldm::utils::DBusHandler().getSubTreePaths(
176 adapterObjPath, 0,
177 std::vector<std::string>({ItemConnector::interface}));
178 }
179 catch (const std::exception& e)
180 {
181 error("No ports under adapter '{ADAPTER_OBJ_PATH}' - {ERROR}.",
182 "ADAPTER_OBJ_PATH", adapterObjPath.c_str(), "ERROR", e);
183 }
184
185 return portObjects;
186}
Ravi Tejace1c96f2020-10-05 23:13:01 -0500187} // namespace utils
188} // namespace responder
189} // namespace pldm