blob: 89fd188c3e24bb7a0f008dd4536894d296e55966 [file] [log] [blame]
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301#include "config.h"
Rashmica Guptac1b66f42022-12-09 16:24:45 +11002#include "libpldm/requester/pldm.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09303#include "base.h"
Rashmica Guptac1b66f42022-12-09 16:24:45 +11004#include "libpldm/transport.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09305
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05306#include <bits/types/struct_iovec.h>
Rashmica Guptac1b66f42022-12-09 16:24:45 +11007#include <stdbool.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09308#include <stdlib.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05309#include <string.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093010#include <sys/socket.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093011#include <sys/un.h>
12#include <unistd.h>
13
Rashmica Guptac1b66f42022-12-09 16:24:45 +110014/* Temporary for old api */
15#include "libpldm/transport/mctp-demux.h"
16extern int
17pldm_transport_mctp_demux_get_socket_fd(struct pldm_transport_mctp_demux *ctx);
18extern struct pldm_transport_mctp_demux *
19pldm_transport_mctp_demux_init_with_fd(int mctp_fd);
20
21/* --- old APIS written in terms of the new API -- */
22/*
23 * pldm_open returns the file descriptor to the MCTP socket, which needs to
24 * persist over api calls (so a consumer can poll it for incoming messages).
25 * So we need a global variable to store the transport struct
26 */
27static struct pldm_transport_mctp_demux *open_transport;
Andrew Jeffery9c766792022-08-10 23:12:49 +093028
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093029LIBPLDM_ABI_STABLE
Andrew Jeffery319304f2023-04-05 13:53:18 +093030pldm_requester_rc_t pldm_open(void)
Andrew Jeffery9c766792022-08-10 23:12:49 +093031{
Rashmica Guptac1b66f42022-12-09 16:24:45 +110032 int fd;
33 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093034
Rashmica Guptac1b66f42022-12-09 16:24:45 +110035 if (open_transport) {
Rashmica Gupta39f88322023-05-12 15:54:12 +100036 fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);
37 return fd;
Andrew Jeffery9c766792022-08-10 23:12:49 +093038 }
39
Rashmica Guptac1b66f42022-12-09 16:24:45 +110040 struct pldm_transport_mctp_demux *demux = NULL;
41 rc = pldm_transport_mctp_demux_init(&demux);
42 if (rc) {
43 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093044 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +110045
46 fd = pldm_transport_mctp_demux_get_socket_fd(demux);
47
48 open_transport = demux;
Andrew Jeffery9c766792022-08-10 23:12:49 +093049
50 return fd;
51}
52
Rashmica Guptac1b66f42022-12-09 16:24:45 +110053/* This macro does the setup and teardown required for the old API to use the
54 * new API. Since the setup/teardown logic is the same for all four send/recv
55 * functions, it makes sense to only define it once. */
Rashmica Gupta0411b712023-05-30 16:43:08 +100056#define PLDM_REQ_FN(eid, fd, fn, rc, ...) \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093057 do { \
58 struct pldm_transport_mctp_demux *demux; \
59 bool using_open_transport = false; \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093060 pldm_tid_t tid = 1; \
61 struct pldm_transport *ctx; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110062 /* The fd can be for a socket we opened or one the consumer \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093063 * opened. */ \
64 if (open_transport && \
65 mctp_fd == pldm_transport_mctp_demux_get_socket_fd( \
66 open_transport)) { \
67 using_open_transport = true; \
68 demux = open_transport; \
69 } else { \
70 demux = pldm_transport_mctp_demux_init_with_fd(fd); \
71 if (!demux) { \
72 rc = PLDM_REQUESTER_OPEN_FAIL; \
73 goto transport_out; \
74 } \
75 } \
76 ctx = pldm_transport_mctp_demux_core(demux); \
77 rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid); \
78 if (rc) { \
79 rc = PLDM_REQUESTER_OPEN_FAIL; \
80 goto transport_out; \
81 } \
82 rc = fn(ctx, tid, __VA_ARGS__); \
83 transport_out: \
84 if (!using_open_transport) { \
85 pldm_transport_mctp_demux_destroy(demux); \
86 } \
Rashmica Gupta0411b712023-05-30 16:43:08 +100087 break; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110088 } while (0)
Andrew Jeffery9c766792022-08-10 23:12:49 +093089
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093090LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093091pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
92 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
93{
Rashmica Gupta0411b712023-05-30 16:43:08 +100094 pldm_requester_rc_t rc = 0;
95 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_recv_msg, rc,
Rashmica Guptac1b66f42022-12-09 16:24:45 +110096 (void **)pldm_resp_msg, resp_msg_len);
Rashmica Gupta0411b712023-05-30 16:43:08 +100097 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
98 if (rc != PLDM_REQUESTER_SUCCESS) {
99 return rc;
100 }
101 if (hdr && (hdr->request || hdr->datagram)) {
102 free(*pldm_resp_msg);
103 *pldm_resp_msg = NULL;
104 return PLDM_REQUESTER_NOT_RESP_MSG;
105 }
106 uint8_t pldm_cc = 0;
107 if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_cc))) {
108 free(*pldm_resp_msg);
109 *pldm_resp_msg = NULL;
110 return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
111 }
112 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113}
114
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930115LIBPLDM_ABI_STABLE
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100116pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd,
117 __attribute__((unused)) uint8_t instance_id,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930118 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
119{
120 pldm_requester_rc_t rc =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930121 pldm_recv_any(eid, mctp_fd, pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930122 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
Rashmica Guptaa3035932023-06-17 12:52:51 +1000123 if (rc == PLDM_REQUESTER_SUCCESS && hdr &&
124 hdr->instance_id != instance_id) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930125 free(*pldm_resp_msg);
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100126 *pldm_resp_msg = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930127 return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
128 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100129 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930130}
131
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930132LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930133pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
134 const uint8_t *pldm_req_msg,
135 size_t req_msg_len, uint8_t **pldm_resp_msg,
136 size_t *resp_msg_len)
137{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000138 pldm_requester_rc_t rc = 0;
139 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
140 if (hdr && !hdr->request) {
141 return PLDM_REQUESTER_NOT_REQ_MSG;
142 }
143 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_recv_msg, rc,
144 pldm_req_msg, req_msg_len, (void **)pldm_resp_msg,
145 resp_msg_len);
146 if (rc != PLDM_REQUESTER_SUCCESS) {
147 return rc;
148 }
149 hdr = (struct pldm_msg_hdr *)pldm_resp_msg;
150 if (hdr && (hdr->request || hdr->datagram)) {
151 free(*pldm_resp_msg);
152 *pldm_resp_msg = NULL;
153 return PLDM_REQUESTER_NOT_RESP_MSG;
154 }
155 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930156}
157
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930158LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930159pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
160 const uint8_t *pldm_req_msg, size_t req_msg_len)
161{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000162 pldm_requester_rc_t rc = 0;
163 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
164 if (!hdr->request) {
165 return PLDM_REQUESTER_NOT_REQ_MSG;
166 }
167 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_msg, rc,
168 (void *)pldm_req_msg, req_msg_len);
169 return rc;
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100170}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930171
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100172/* Adding this here for completeness in the case we can't smoothly
173 * transition apps over to the new api */
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930174LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930175void pldm_close(void)
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100176{
177 if (open_transport) {
178 pldm_transport_mctp_demux_destroy(open_transport);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930179 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100180 open_transport = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930181}