blob: 8e8863590a12bd20ce4557992fa7fb4afd95f9c2 [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Andrew Jeffery860a43d2024-08-23 01:21:58 +00002#include "compiler.h"
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10303#include <libpldm/base.h>
Andrew Jefferyd12dd362023-11-10 15:36:38 +10304#include <libpldm/pldm.h>
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10305#include <libpldm/transport.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09306
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <bits/types/struct_iovec.h>
Andrew Jeffery4e1ba8a2023-06-29 10:48:33 +09308#include <fcntl.h>
Rashmica Guptac1b66f42022-12-09 16:24:45 +11009#include <stdbool.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093010#include <stdlib.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053011#include <string.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <sys/socket.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093013#include <sys/un.h>
14#include <unistd.h>
15
Rashmica Guptac1b66f42022-12-09 16:24:45 +110016/* Temporary for old api */
Andrew Jefferyefb40062023-11-10 13:48:39 +103017#include <libpldm/transport/mctp-demux.h>
Rashmica Guptac1b66f42022-12-09 16:24:45 +110018extern int
19pldm_transport_mctp_demux_get_socket_fd(struct pldm_transport_mctp_demux *ctx);
20extern struct pldm_transport_mctp_demux *
21pldm_transport_mctp_demux_init_with_fd(int mctp_fd);
22
23/* --- old APIS written in terms of the new API -- */
24/*
25 * pldm_open returns the file descriptor to the MCTP socket, which needs to
26 * persist over api calls (so a consumer can poll it for incoming messages).
27 * So we need a global variable to store the transport struct
28 */
29static struct pldm_transport_mctp_demux *open_transport;
Andrew Jeffery9c766792022-08-10 23:12:49 +093030
Andrew Jeffery0a6d6822023-08-22 21:40:32 +093031LIBPLDM_ABI_DEPRECATED
Andrew Jeffery319304f2023-04-05 13:53:18 +093032pldm_requester_rc_t pldm_open(void)
Andrew Jeffery9c766792022-08-10 23:12:49 +093033{
Andrew Jeffery4e1ba8a2023-06-29 10:48:33 +093034 int fd = PLDM_REQUESTER_OPEN_FAIL;
Andrew Jeffery9c766792022-08-10 23:12:49 +093035
Rashmica Guptac1b66f42022-12-09 16:24:45 +110036 if (open_transport) {
Rashmica Gupta39f88322023-05-12 15:54:12 +100037 fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);
Andrew Jeffery4e1ba8a2023-06-29 10:48:33 +093038
39 /* If someone has externally issued close() on fd then we need to start again. Use
40 * `fcntl(..., F_GETFD)` to test whether fd is valid. */
41 if (fd < 0 || fcntl(fd, F_GETFD) < 0) {
42 pldm_close();
43 }
Andrew Jeffery9c766792022-08-10 23:12:49 +093044 }
45
Andrew Jeffery4e1ba8a2023-06-29 10:48:33 +093046 /* We retest open_transport as it may have been set to NULL by pldm_close() above. */
47 if (!open_transport) {
48 struct pldm_transport_mctp_demux *demux = NULL;
49
50 if (pldm_transport_mctp_demux_init(&demux) < 0) {
51 return PLDM_REQUESTER_OPEN_FAIL;
52 }
53
54 open_transport = demux;
55
56 fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);
Andrew Jeffery9c766792022-08-10 23:12:49 +093057 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +110058
Andrew Jeffery9c766792022-08-10 23:12:49 +093059 return fd;
60}
61
Rashmica Guptac1b66f42022-12-09 16:24:45 +110062/* This macro does the setup and teardown required for the old API to use the
63 * new API. Since the setup/teardown logic is the same for all four send/recv
64 * functions, it makes sense to only define it once. */
Rashmica Gupta0411b712023-05-30 16:43:08 +100065#define PLDM_REQ_FN(eid, fd, fn, rc, ...) \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093066 do { \
67 struct pldm_transport_mctp_demux *demux; \
68 bool using_open_transport = false; \
Rashmica Guptad10c6b02023-07-24 13:09:48 +100069 pldm_tid_t tid = eid; \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093070 struct pldm_transport *ctx; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110071 /* The fd can be for a socket we opened or one the consumer \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093072 * opened. */ \
73 if (open_transport && \
74 mctp_fd == pldm_transport_mctp_demux_get_socket_fd( \
75 open_transport)) { \
76 using_open_transport = true; \
77 demux = open_transport; \
78 } else { \
79 demux = pldm_transport_mctp_demux_init_with_fd(fd); \
80 if (!demux) { \
81 rc = PLDM_REQUESTER_OPEN_FAIL; \
82 goto transport_out; \
83 } \
84 } \
85 ctx = pldm_transport_mctp_demux_core(demux); \
86 rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid); \
87 if (rc) { \
88 rc = PLDM_REQUESTER_OPEN_FAIL; \
89 goto transport_out; \
90 } \
91 rc = fn(ctx, tid, __VA_ARGS__); \
92 transport_out: \
93 if (!using_open_transport) { \
94 pldm_transport_mctp_demux_destroy(demux); \
95 } \
Rashmica Gupta0411b712023-05-30 16:43:08 +100096 break; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110097 } while (0)
Andrew Jeffery9c766792022-08-10 23:12:49 +093098
Andrew Jeffery0a6d6822023-08-22 21:40:32 +093099LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930100pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
101 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
102{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000103 pldm_requester_rc_t rc = 0;
Rashmica Gupta24576292023-07-31 14:02:41 +1000104
105 struct pldm_transport_mctp_demux *demux;
106 bool using_open_transport = false;
107 pldm_tid_t tid = eid;
108 struct pldm_transport *ctx;
109 /* The fd can be for a socket we opened or one the consumer
110 * opened. */
111 if (open_transport &&
112 mctp_fd ==
113 pldm_transport_mctp_demux_get_socket_fd(open_transport)) {
114 using_open_transport = true;
115 demux = open_transport;
116 } else {
117 demux = pldm_transport_mctp_demux_init_with_fd(mctp_fd);
118 if (!demux) {
119 rc = PLDM_REQUESTER_OPEN_FAIL;
120 goto transport_out;
121 }
122 }
123 ctx = pldm_transport_mctp_demux_core(demux);
124 rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid);
125 if (rc) {
126 rc = PLDM_REQUESTER_OPEN_FAIL;
127 goto transport_out;
128 }
129 /* TODO this is the only change, can we work this into the macro? */
130 rc = pldm_transport_recv_msg(ctx, &tid, (void **)pldm_resp_msg,
131 resp_msg_len);
132
Rashmica Gupta0411b712023-05-30 16:43:08 +1000133 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
134 if (rc != PLDM_REQUESTER_SUCCESS) {
135 return rc;
136 }
137 if (hdr && (hdr->request || hdr->datagram)) {
138 free(*pldm_resp_msg);
139 *pldm_resp_msg = NULL;
140 return PLDM_REQUESTER_NOT_RESP_MSG;
141 }
142 uint8_t pldm_cc = 0;
143 if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_cc))) {
144 free(*pldm_resp_msg);
145 *pldm_resp_msg = NULL;
146 return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
147 }
Rashmica Gupta24576292023-07-31 14:02:41 +1000148
149transport_out:
150 if (!using_open_transport) {
151 pldm_transport_mctp_demux_destroy(demux);
152 }
153
Rashmica Gupta0411b712023-05-30 16:43:08 +1000154 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930155}
156
Andrew Jeffery0a6d6822023-08-22 21:40:32 +0930157LIBPLDM_ABI_DEPRECATED
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100158pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd,
Andrew Jeffery860a43d2024-08-23 01:21:58 +0000159 LIBPLDM_CC_UNUSED uint8_t instance_id,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930160 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
161{
162 pldm_requester_rc_t rc =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930163 pldm_recv_any(eid, mctp_fd, pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930164 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
Rashmica Guptaa3035932023-06-17 12:52:51 +1000165 if (rc == PLDM_REQUESTER_SUCCESS && hdr &&
166 hdr->instance_id != instance_id) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930167 free(*pldm_resp_msg);
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100168 *pldm_resp_msg = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930169 return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
170 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100171 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930172}
173
Andrew Jeffery0a6d6822023-08-22 21:40:32 +0930174LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930175pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
176 const uint8_t *pldm_req_msg,
177 size_t req_msg_len, uint8_t **pldm_resp_msg,
178 size_t *resp_msg_len)
179{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000180 pldm_requester_rc_t rc = 0;
181 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
182 if (hdr && !hdr->request) {
183 return PLDM_REQUESTER_NOT_REQ_MSG;
184 }
185 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_recv_msg, rc,
186 pldm_req_msg, req_msg_len, (void **)pldm_resp_msg,
187 resp_msg_len);
188 if (rc != PLDM_REQUESTER_SUCCESS) {
189 return rc;
190 }
Thu Nguyen43a79852023-07-17 16:22:11 +0700191 hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
Rashmica Gupta0411b712023-05-30 16:43:08 +1000192 if (hdr && (hdr->request || hdr->datagram)) {
193 free(*pldm_resp_msg);
194 *pldm_resp_msg = NULL;
195 return PLDM_REQUESTER_NOT_RESP_MSG;
196 }
197 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930198}
199
Andrew Jeffery0a6d6822023-08-22 21:40:32 +0930200LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930201pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
202 const uint8_t *pldm_req_msg, size_t req_msg_len)
203{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000204 pldm_requester_rc_t rc = 0;
205 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
206 if (!hdr->request) {
207 return PLDM_REQUESTER_NOT_REQ_MSG;
208 }
209 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_msg, rc,
210 (void *)pldm_req_msg, req_msg_len);
211 return rc;
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100212}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930213
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100214/* Adding this here for completeness in the case we can't smoothly
215 * transition apps over to the new api */
Andrew Jeffery0a6d6822023-08-22 21:40:32 +0930216LIBPLDM_ABI_DEPRECATED
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930217void pldm_close(void)
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100218{
219 if (open_transport) {
220 pldm_transport_mctp_demux_destroy(open_transport);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930221 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100222 open_transport = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930223}