blob: c78512f6bcccaa7c852f1e24809b8ca6b72ed3ca [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 Jeffery319304f2023-04-05 13:53:18 +093028pldm_requester_rc_t pldm_open(void)
Andrew Jeffery9c766792022-08-10 23:12:49 +093029{
Rashmica Guptac1b66f42022-12-09 16:24:45 +110030 int fd;
31 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093032
Rashmica Guptac1b66f42022-12-09 16:24:45 +110033 if (open_transport) {
34 return -1;
Andrew Jeffery9c766792022-08-10 23:12:49 +093035 }
36
Rashmica Guptac1b66f42022-12-09 16:24:45 +110037 struct pldm_transport_mctp_demux *demux = NULL;
38 rc = pldm_transport_mctp_demux_init(&demux);
39 if (rc) {
40 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +093041 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +110042
43 fd = pldm_transport_mctp_demux_get_socket_fd(demux);
44
45 open_transport = demux;
Andrew Jeffery9c766792022-08-10 23:12:49 +093046
47 return fd;
48}
49
Rashmica Guptac1b66f42022-12-09 16:24:45 +110050/* This macro does the setup and teardown required for the old API to use the
51 * new API. Since the setup/teardown logic is the same for all four send/recv
52 * functions, it makes sense to only define it once. */
53#define PLDM_REQ_FN(eid, fd, fn, ...) \
54 do { \
55 struct pldm_transport_mctp_demux *demux; \
56 bool using_open_transport = false; \
57 pldm_requester_rc_t rc; \
58 pldm_tid_t tid = 1; \
59 struct pldm_transport *ctx; \
60 /* The fd can be for a socket we opened or one the consumer \
61 * opened. */ \
62 if (open_transport && \
63 mctp_fd == pldm_transport_mctp_demux_get_socket_fd( \
64 open_transport)) { \
65 using_open_transport = true; \
66 demux = open_transport; \
67 } else { \
68 demux = pldm_transport_mctp_demux_init_with_fd(fd); \
69 if (!demux) { \
70 rc = PLDM_REQUESTER_OPEN_FAIL; \
71 goto transport_out; \
72 } \
73 } \
74 ctx = pldm_transport_mctp_demux_core(demux); \
75 rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid); \
76 if (rc) { \
77 rc = PLDM_REQUESTER_OPEN_FAIL; \
78 goto transport_out; \
79 } \
80 rc = fn(ctx, tid, __VA_ARGS__); \
81 transport_out: \
82 if (!using_open_transport) { \
83 pldm_transport_mctp_demux_destroy(demux); \
84 } \
85 return rc; \
86 } while (0)
Andrew Jeffery9c766792022-08-10 23:12:49 +093087
88pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
89 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
90{
Rashmica Guptac1b66f42022-12-09 16:24:45 +110091 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_recv_msg,
92 (void **)pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +093093}
94
Rashmica Guptac1b66f42022-12-09 16:24:45 +110095pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd,
96 __attribute__((unused)) uint8_t instance_id,
Andrew Jeffery9c766792022-08-10 23:12:49 +093097 uint8_t **pldm_resp_msg, size_t *resp_msg_len)
98{
99 pldm_requester_rc_t rc =
100 pldm_recv_any(eid, mctp_fd, pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930101 struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
102 if (hdr->instance_id != instance_id) {
103 free(*pldm_resp_msg);
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100104 *pldm_resp_msg = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930105 return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
106 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100107 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930108}
109
110pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
111 const uint8_t *pldm_req_msg,
112 size_t req_msg_len, uint8_t **pldm_resp_msg,
113 size_t *resp_msg_len)
114{
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100115 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_recv_msg, pldm_req_msg,
116 req_msg_len, (void **)pldm_resp_msg, resp_msg_len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930117}
118
119pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
120 const uint8_t *pldm_req_msg, size_t req_msg_len)
121{
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100122 PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_msg, (void *)pldm_req_msg,
123 req_msg_len);
124}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930125
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100126/* Adding this here for completeness in the case we can't smoothly
127 * transition apps over to the new api */
128void pldm_close()
129{
130 if (open_transport) {
131 pldm_transport_mctp_demux_destroy(open_transport);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132 }
Rashmica Guptac1b66f42022-12-09 16:24:45 +1100133 open_transport = NULL;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930134}