blob: 9fec1a17d43a711dcae6dbda3eff9e6f3828a6a6 [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>
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -05006#include <libpldm/platform.h>
Ravi Tejace1c96f2020-10-05 23:13:01 -05007#include <sys/socket.h>
8#include <sys/types.h>
9#include <sys/un.h>
10#include <unistd.h>
11
Riya Dixit49cfb132023-03-02 04:26:53 -060012#include <phosphor-logging/lg2.hpp>
Sampa Misra245fc6f2021-08-12 10:30:34 -050013#include <xyz/openbmc_project/Inventory/Decorator/Asset/client.hpp>
Pavithra Barithaya9e0e8262024-04-15 09:12:16 -050014#include <xyz/openbmc_project/Inventory/Item/Connector/client.hpp>
15#include <xyz/openbmc_project/ObjectMapper/client.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060016
Riya Dixit49cfb132023-03-02 04:26:53 -060017PHOSPHOR_LOG2_USING;
18
Kamalkumar Patel7d427f12024-05-16 03:44:00 -050019using namespace pldm::utils;
20
Ravi Tejace1c96f2020-10-05 23:13:01 -050021namespace pldm
22{
23namespace responder
24{
25namespace utils
26{
Ravi Tejace1c96f2020-10-05 23:13:01 -050027int setupUnixSocket(const std::string& socketInterface)
28{
29 int sock;
30 struct sockaddr_un addr;
31 memset(&addr, 0, sizeof(addr));
32 addr.sun_family = AF_UNIX;
Patrick Williams16c2a0a2024-08-16 15:20:59 -040033 size_t interfaceLength =
34 strnlen(socketInterface.c_str(), sizeof(addr.sun_path));
Riya Dixitfc84f632024-04-06 14:00:02 -050035 if (interfaceLength == sizeof(addr.sun_path))
Ravi Tejace1c96f2020-10-05 23:13:01 -050036 {
Riya Dixitfc84f632024-04-06 14:00:02 -050037 error("Setup unix socket path '{PATH}' is too long '{LENGTH}'", "PATH",
38 socketInterface, "LENGTH", interfaceLength);
Ravi Tejace1c96f2020-10-05 23:13:01 -050039 return -1;
40 }
41
42 strncpy(addr.sun_path, socketInterface.c_str(), sizeof(addr.sun_path) - 1);
43
44 if ((sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
45 {
Riya Dixitfc84f632024-04-06 14:00:02 -050046 error("Failed to open unix socket");
Ravi Tejace1c96f2020-10-05 23:13:01 -050047 return -1;
48 }
49
50 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
51 {
Riya Dixitfc84f632024-04-06 14:00:02 -050052 error("Failed to bind unix socket, error number - {ERROR_NUM}",
53 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050054 close(sock);
55 return -1;
56 }
57
58 if (listen(sock, 1) == -1)
59 {
Riya Dixitfc84f632024-04-06 14:00:02 -050060 error("Failed listen() call while setting up unix socket");
Ravi Tejace1c96f2020-10-05 23:13:01 -050061 close(sock);
62 return -1;
63 }
64
65 fd_set rfd;
66 struct timeval tv;
67 tv.tv_sec = 1;
68 tv.tv_usec = 0;
69
70 FD_ZERO(&rfd);
71 FD_SET(sock, &rfd);
72 int nfd = sock + 1;
Andrew Geisslerefbb5942020-12-15 10:12:30 -060073 int fd = -1;
Ravi Tejace1c96f2020-10-05 23:13:01 -050074
75 int retval = select(nfd, &rfd, NULL, NULL, &tv);
76 if (retval < 0)
77 {
Riya Dixitfc84f632024-04-06 14:00:02 -050078 error(
79 "Failed select() call while setting up unix socket, error number - {ERROR_NUM}",
80 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050081 close(sock);
82 return -1;
83 }
84
85 if ((retval > 0) && (FD_ISSET(sock, &rfd)))
86 {
87 fd = accept(sock, NULL, NULL);
88 if (fd < 0)
89 {
Riya Dixitfc84f632024-04-06 14:00:02 -050090 error(
91 "Failed accept() call while setting up unix socket, error number - {ERROR_NUM}",
92 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050093 close(sock);
94 return -1;
95 }
96 close(sock);
97 }
98 return fd;
99}
100
101int writeToUnixSocket(const int sock, const char* buf, const uint64_t blockSize)
102{
103 uint64_t i;
104 int nwrite = 0;
105
106 for (i = 0; i < blockSize; i = i + nwrite)
107 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500108 fd_set wfd;
109 struct timeval tv;
110 tv.tv_sec = 1;
111 tv.tv_usec = 0;
112
113 FD_ZERO(&wfd);
114 FD_SET(sock, &wfd);
115 int nfd = sock + 1;
116
117 int retval = select(nfd, NULL, &wfd, NULL, &tv);
118 if (retval < 0)
119 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500120 error(
121 "Failed to write to unix socket select, error number - {ERROR_NUM}",
122 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500123 close(sock);
124 return -1;
125 }
126 if (retval == 0)
127 {
128 nwrite = 0;
129 continue;
130 }
131 if ((retval > 0) && (FD_ISSET(sock, &wfd)))
132 {
133 nwrite = write(sock, buf + i, blockSize - i);
134 if (nwrite < 0)
135 {
136 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
137 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600138 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500139 "Failed to write to unix socket, error number - {ERROR_NUM}",
140 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500141 nwrite = 0;
142 continue;
143 }
Riya Dixitfc84f632024-04-06 14:00:02 -0500144 error(
145 "Failed to write to unix socket, error number - {ERROR_NUM}",
146 "ERROR_NUM", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500147 close(sock);
148 return -1;
149 }
150 }
151 else
152 {
153 nwrite = 0;
154 }
155 }
156 return 0;
157}
158
Sampa Misra245fc6f2021-08-12 10:30:34 -0500159bool checkIfIBMFru(const std::string& objPath)
160{
161 using DecoratorAsset =
162 sdbusplus::client::xyz::openbmc_project::inventory::decorator::Asset<>;
163
164 try
165 {
166 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
167 objPath.c_str(), "Model", DecoratorAsset::interface);
168 const auto& model = std::get<std::string>(propVal);
169 if (!model.empty())
170 {
171 return true;
172 }
173 }
174 catch (const std::exception&)
175 {
176 return false;
177 }
178 return false;
179}
180
Pavithra Barithaya9e0e8262024-04-15 09:12:16 -0500181std::vector<std::string> findPortObjects(const std::string& adapterObjPath)
182{
183 using ItemConnector =
184 sdbusplus::client::xyz::openbmc_project::inventory::item::Connector<>;
185
186 std::vector<std::string> portObjects;
187 try
188 {
189 portObjects = pldm::utils::DBusHandler().getSubTreePaths(
190 adapterObjPath, 0,
191 std::vector<std::string>({ItemConnector::interface}));
192 }
193 catch (const std::exception& e)
194 {
195 error("No ports under adapter '{ADAPTER_OBJ_PATH}' - {ERROR}.",
196 "ADAPTER_OBJ_PATH", adapterObjPath.c_str(), "ERROR", e);
197 }
198
199 return portObjects;
200}
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500201
Ravi Tejace1c96f2020-10-05 23:13:01 -0500202} // namespace utils
Kamalkumar Pateleb43d6c2024-05-01 06:11:31 -0500203
204namespace oem_ibm_utils
205{
206using namespace pldm::utils;
207
208int pldm::responder::oem_ibm_utils::Handler::setCoreCount(
209 const EntityAssociations& Associations, const EntityMaps entityMaps)
210{
211 int coreCountRef = 0;
212 // get the CPU pldm entities
213 for (const auto& entries : Associations)
214 {
215 auto parent = pldm_entity_extract(entries[0]);
216 // entries[0] would be the parent in the entity association map
217 if (parent.entity_type == PLDM_ENTITY_PROC)
218 {
219 int& coreCount = coreCountRef;
220 for (const auto& entry : entries)
221 {
222 auto child = pldm_entity_extract(entry);
223 if (child.entity_type == (PLDM_ENTITY_PROC | 0x8000))
224 {
225 // got a core child
226 ++coreCount;
227 }
228 }
229 try
230 {
231 auto grand_parent = pldm_entity_get_parent(entries[0]);
232 std::string grepWord = std::format(
233 "{}{}/{}{}", entityMaps.at(grand_parent.entity_type),
234 std::to_string(grand_parent.entity_instance_num),
235 entityMaps.at(parent.entity_type),
236 std::to_string(parent.entity_instance_num));
237 static constexpr auto searchpath = "/xyz/openbmc_project/";
238 std::vector<std::string> cpuInterface = {
239 "xyz.openbmc_project.Inventory.Item.Cpu"};
240 pldm::utils::GetSubTreeResponse response = dBusIntf->getSubtree(
241 searchpath, 0 /* depth */, cpuInterface);
242 for (const auto& [objectPath, serviceMap] : response)
243 {
244 // find the object path with first occurance of coreX
245 if (objectPath.contains(grepWord))
246 {
247 pldm::utils::DBusMapping dbusMapping{
248 objectPath, cpuInterface[0], "CoreCount",
249 "uint16_t"};
250 pldm::utils::PropertyValue value =
251 static_cast<uint16_t>(coreCount);
252 try
253 {
254 dBusIntf->setDbusProperty(dbusMapping, value);
255 }
256 catch (const std::exception& e)
257 {
258 error(
259 "Failed to set the core count property at interface '{INTERFACE}': {ERROR}",
260 "INTERFACE", cpuInterface[0], "ERROR", e);
261 }
262 }
263 }
264 }
265 catch (const std::exception& e)
266 {
267 error("Failed to searching CoreCount property: {ERROR}",
268 "ERROR", e);
269 }
270 }
271 }
272 return coreCountRef;
273}
274
275} // namespace oem_ibm_utils
Ravi Tejace1c96f2020-10-05 23:13:01 -0500276} // namespace responder
277} // namespace pldm