blob: f8bcdc3aadb69a8ea0fcb14f74561939edcf0b6a [file] [log] [blame]
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +10001#include "common/transport.hpp"
2
3#include <libpldm/transport.h>
4#include <libpldm/transport/af-mctp.h>
5#include <libpldm/transport/mctp-demux.h>
6
7#include <algorithm>
8#include <ranges>
9#include <system_error>
10
Amithash Prasade7ae8042025-09-11 13:47:05 -070011struct pldm_transport* transport_impl_init(TransportImpl& impl, pollfd& pollfd,
12 bool listening);
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100013void transport_impl_destroy(TransportImpl& impl);
14
15static constexpr uint8_t MCTP_EID_VALID_MIN = 8;
16static constexpr uint8_t MCTP_EID_VALID_MAX = 255;
17
18/*
19 * Currently the OpenBMC ecosystem assumes TID == EID. Pre-populate the TID
20 * mappings over the EID space excluding the Null (0), Reserved (1 to 7),
21 * Broadcast EIDs (255) defined by Section 8.2 Special endpoint IDs in DSP0236
22 * v1.3.1. Further, by Section 8.1.1 SetTID command (0x01) in DSP0240 v1.1.0,
23 * the TIDs 0x00 and 0xff are also reserved. These overlap with the reserved
24 * EIDs so no additional filtering is required.
25 *
26 * Further, pldmtool and pldmd are two separate processes. They are opening two
27 * different sockets, but with the mctp-demux-daemon, the response messages are
28 * broadcasted to all sockets. When pldmd receives the response for a request
29 * issued by pldmtool, pldm_transport_mctp_demux_recv() may return with error
30 * PLDM_REQUESTER_RECV_FAIL if it fails to map the EID of the source endpoint to
31 * its TID. The EID to TID mappings of pldmtool and pldmd should be coherent to
32 * prevent the failure of pldm_transport_mctp_demux_recv().
33 */
34
35[[maybe_unused]] static struct pldm_transport*
36 pldm_transport_impl_mctp_demux_init(TransportImpl& impl, pollfd& pollfd)
37{
38 impl.mctp_demux = nullptr;
39 pldm_transport_mctp_demux_init(&impl.mctp_demux);
40 if (!impl.mctp_demux)
41 {
42 return nullptr;
43 }
44
45 for (const auto eid :
46 std::views::iota(MCTP_EID_VALID_MIN, MCTP_EID_VALID_MAX))
47 {
48 int rc = pldm_transport_mctp_demux_map_tid(impl.mctp_demux, eid, eid);
49 if (rc)
50 {
51 pldm_transport_af_mctp_destroy(impl.af_mctp);
52 return nullptr;
53 }
54 }
55
56 pldm_transport* pldmTransport =
57 pldm_transport_mctp_demux_core(impl.mctp_demux);
58
59 if (pldmTransport != nullptr)
60 {
61 pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
62 }
63
64 return pldmTransport;
65}
66
Patrick Williams366507c2025-02-03 14:28:01 -050067[[maybe_unused]] static struct pldm_transport* pldm_transport_impl_af_mctp_init(
Amithash Prasade7ae8042025-09-11 13:47:05 -070068 TransportImpl& impl, pollfd& pollfd, bool listening)
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100069{
70 impl.af_mctp = nullptr;
71 pldm_transport_af_mctp_init(&impl.af_mctp);
72 if (!impl.af_mctp)
73 {
74 return nullptr;
75 }
76
77 for (const auto eid :
78 std::views::iota(MCTP_EID_VALID_MIN, MCTP_EID_VALID_MAX))
79 {
80 int rc = pldm_transport_af_mctp_map_tid(impl.af_mctp, eid, eid);
81 if (rc)
82 {
83 pldm_transport_af_mctp_destroy(impl.af_mctp);
84 return nullptr;
85 }
86 }
87
88 /* Listen for requests on any interface */
Amithash Prasade7ae8042025-09-11 13:47:05 -070089 if (listening && pldm_transport_af_mctp_bind(impl.af_mctp, nullptr, 0))
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100090 {
91 return nullptr;
92 }
93
94 pldm_transport* pldmTransport = pldm_transport_af_mctp_core(impl.af_mctp);
95
96 if (pldmTransport != nullptr)
97 {
98 pldm_transport_af_mctp_init_pollfd(pldmTransport, &pollfd);
99 }
100
101 return pldmTransport;
102}
103
Amithash Prasade7ae8042025-09-11 13:47:05 -0700104struct pldm_transport* transport_impl_init(TransportImpl& impl, pollfd& pollfd,
105 [[maybe_unused]] bool listening)
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000106{
107#if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
108 return pldm_transport_impl_mctp_demux_init(impl, pollfd);
109#elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
Amithash Prasade7ae8042025-09-11 13:47:05 -0700110 return pldm_transport_impl_af_mctp_init(impl, pollfd, listening);
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000111#else
112 return nullptr;
113#endif
114}
115
116void transport_impl_destroy(TransportImpl& impl)
117{
118#if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
119 pldm_transport_mctp_demux_destroy(impl.mctp_demux);
120#elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
121 pldm_transport_af_mctp_destroy(impl.af_mctp);
122#endif
123}
124
Amithash Prasade7ae8042025-09-11 13:47:05 -0700125PldmTransport::PldmTransport(bool listening)
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000126{
Amithash Prasade7ae8042025-09-11 13:47:05 -0700127 transport = transport_impl_init(impl, pfd, listening);
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000128 if (!transport)
129 {
130 throw std::system_error(ENOMEM, std::generic_category());
131 }
132}
133
134PldmTransport::~PldmTransport()
135{
136 transport_impl_destroy(impl);
137}
138
139int PldmTransport::getEventSource() const
140{
141 return pfd.fd;
142}
143
144pldm_requester_rc_t PldmTransport::sendMsg(pldm_tid_t tid, const void* tx,
145 size_t len)
146{
147 return pldm_transport_send_msg(transport, tid, tx, len);
148}
149
150pldm_requester_rc_t PldmTransport::recvMsg(pldm_tid_t& tid, void*& rx,
151 size_t& len)
152{
153 return pldm_transport_recv_msg(transport, &tid, (void**)&rx, &len);
154}
155
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400156pldm_requester_rc_t PldmTransport::sendRecvMsg(
157 pldm_tid_t tid, const void* tx, size_t txLen, void*& rx, size_t& rxLen)
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000158{
159 return pldm_transport_send_recv_msg(transport, tid, tx, txLen, &rx, &rxLen);
160}