blob: 78e1e52eef8a01f21f687d3c0b0490313c07e05b [file] [log] [blame]
Rashmica Guptac1b66f42022-12-09 16:24:45 +11001#include "libpldm/requester/pldm.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09302#include "base.h"
Rashmica Guptac1b66f42022-12-09 16:24:45 +11003#include "libpldm/transport.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09304
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05305#include <bits/types/struct_iovec.h>
Rashmica Guptac1b66f42022-12-09 16:24:45 +11006#include <stdbool.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09307#include <stdlib.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05308#include <string.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <sys/socket.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093010#include <sys/un.h>
11#include <unistd.h>
12
Rashmica Guptac1b66f42022-12-09 16:24:45 +110013/* Temporary for old api */
14#include "libpldm/transport/mctp-demux.h"
15extern int
16pldm_transport_mctp_demux_get_socket_fd(struct pldm_transport_mctp_demux *ctx);
17extern struct pldm_transport_mctp_demux *
18pldm_transport_mctp_demux_init_with_fd(int mctp_fd);
19
20/* --- old APIS written in terms of the new API -- */
21/*
22 * pldm_open returns the file descriptor to the MCTP socket, which needs to
23 * persist over api calls (so a consumer can poll it for incoming messages).
24 * So we need a global variable to store the transport struct
25 */
26static struct pldm_transport_mctp_demux *open_transport;
Andrew Jeffery9c766792022-08-10 23:12:49 +093027
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093028LIBPLDM_ABI_STABLE
Andrew Jeffery319304f2023-04-05 13:53:18 +093029pldm_requester_rc_t pldm_open(void)
Andrew Jeffery9c766792022-08-10 23:12:49 +093030{
Rashmica Guptac1b66f42022-12-09 16:24:45 +110031 int fd;
32 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093033
Rashmica Guptac1b66f42022-12-09 16:24:45 +110034 if (open_transport) {
Rashmica Gupta39f88322023-05-12 15:54:12 +100035 fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);
36 return fd;
Andrew Jeffery9c766792022-08-10 23:12:49 +093037 }
38
Rashmica Guptac1b66f42022-12-09 16:24:45 +110039 struct pldm_transport_mctp_demux *demux = NULL;
40 rc = pldm_transport_mctp_demux_init(&demux);
41 if (rc) {
42 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093043 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +110044
45 fd = pldm_transport_mctp_demux_get_socket_fd(demux);
46
47 open_transport = demux;
Andrew Jeffery9c766792022-08-10 23:12:49 +093048
49 return fd;
50}
51
Rashmica Guptac1b66f42022-12-09 16:24:45 +110052/* This macro does the setup and teardown required for the old API to use the
53 * new API. Since the setup/teardown logic is the same for all four send/recv
54 * functions, it makes sense to only define it once. */
Rashmica Gupta0411b712023-05-30 16:43:08 +100055#define PLDM_REQ_FN(eid, fd, fn, rc, ...) \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093056 do { \
57 struct pldm_transport_mctp_demux *demux; \
58 bool using_open_transport = false; \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093059 pldm_tid_t tid = 1; \
60 struct pldm_transport *ctx; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110061 /* The fd can be for a socket we opened or one the consumer \
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093062 * opened. */ \
63 if (open_transport && \
64 mctp_fd == pldm_transport_mctp_demux_get_socket_fd( \
65 open_transport)) { \
66 using_open_transport = true; \
67 demux = open_transport; \
68 } else { \
69 demux = pldm_transport_mctp_demux_init_with_fd(fd); \
70 if (!demux) { \
71 rc = PLDM_REQUESTER_OPEN_FAIL; \
72 goto transport_out; \
73 } \
74 } \
75 ctx = pldm_transport_mctp_demux_core(demux); \
76 rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid); \
77 if (rc) { \
78 rc = PLDM_REQUESTER_OPEN_FAIL; \
79 goto transport_out; \
80 } \
81 rc = fn(ctx, tid, __VA_ARGS__); \
82 transport_out: \
83 if (!using_open_transport) { \
84 pldm_transport_mctp_demux_destroy(demux); \
85 } \
Rashmica Gupta0411b712023-05-30 16:43:08 +100086 break; \
Rashmica Guptac1b66f42022-12-09 16:24:45 +110087 } while (0)
Andrew Jeffery9c766792022-08-10 23:12:49 +093088
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093089LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093090pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
91 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
92{
Rashmica Gupta0411b712023-05-30 16:43:08 +100093 pldm_requester_rc_t rc = 0;
94 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_recv_msg, rc,
Rashmica Guptac1b66f42022-12-09 16:24:45 +110095 (void **)pldm_resp_msg, resp_msg_len);
Rashmica Gupta0411b712023-05-30 16:43:08 +100096 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
97 if (rc != PLDM_REQUESTER_SUCCESS) {
98 return rc;
99 }
100 if (hdr && (hdr->request || hdr->datagram)) {
101 free(*pldm_resp_msg);
102 *pldm_resp_msg = NULL;
103 return PLDM_REQUESTER_NOT_RESP_MSG;
104 }
105 uint8_t pldm_cc = 0;
106 if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_cc))) {
107 free(*pldm_resp_msg);
108 *pldm_resp_msg = NULL;
109 return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
110 }
111 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930112}
113
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930114LIBPLDM_ABI_STABLE
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100115pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd,
116 __attribute__((unused)) uint8_t instance_id,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930117 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
118{
119 pldm_requester_rc_t rc =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930120 pldm_recv_any(eid, mctp_fd, pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930121 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
Rashmica Guptaa3035932023-06-17 12:52:51 +1000122 if (rc == PLDM_REQUESTER_SUCCESS && hdr &&
123 hdr->instance_id != instance_id) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930124 free(*pldm_resp_msg);
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100125 *pldm_resp_msg = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930126 return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
127 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100128 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930129}
130
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930131LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
133 const uint8_t *pldm_req_msg,
134 size_t req_msg_len, uint8_t **pldm_resp_msg,
135 size_t *resp_msg_len)
136{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000137 pldm_requester_rc_t rc = 0;
138 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
139 if (hdr && !hdr->request) {
140 return PLDM_REQUESTER_NOT_REQ_MSG;
141 }
142 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_recv_msg, rc,
143 pldm_req_msg, req_msg_len, (void **)pldm_resp_msg,
144 resp_msg_len);
145 if (rc != PLDM_REQUESTER_SUCCESS) {
146 return rc;
147 }
148 hdr = (struct pldm_msg_hdr *)pldm_resp_msg;
149 if (hdr && (hdr->request || hdr->datagram)) {
150 free(*pldm_resp_msg);
151 *pldm_resp_msg = NULL;
152 return PLDM_REQUESTER_NOT_RESP_MSG;
153 }
154 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930155}
156
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930157LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930158pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
159 const uint8_t *pldm_req_msg, size_t req_msg_len)
160{
Rashmica Gupta0411b712023-05-30 16:43:08 +1000161 pldm_requester_rc_t rc = 0;
162 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
163 if (!hdr->request) {
164 return PLDM_REQUESTER_NOT_REQ_MSG;
165 }
166 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_msg, rc,
167 (void *)pldm_req_msg, req_msg_len);
168 return rc;
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100169}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930170
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100171/* Adding this here for completeness in the case we can't smoothly
172 * transition apps over to the new api */
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930173LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930174void pldm_close(void)
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100175{
176 if (open_transport) {
177 pldm_transport_mctp_demux_destroy(open_transport);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930178 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100179 open_transport = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930180}