xref: /openbmc/dbus-sensors/src/MctpAsioEndpoint.hpp (revision 6d481b5d0636dc3adaa00c2292ac92fc8840fd94)
1*6d481b5dSEd Tanous #pragma once
2*6d481b5dSEd Tanous 
3*6d481b5dSEd Tanous #include <boost/asio/generic/datagram_protocol.hpp>
4*6d481b5dSEd Tanous #include <phosphor-logging/lg2.hpp>
5*6d481b5dSEd Tanous 
6*6d481b5dSEd Tanous #include <optional>
7*6d481b5dSEd Tanous #include <utility>
8*6d481b5dSEd Tanous 
9*6d481b5dSEd Tanous // Becuase of issues with glibc not matching linux, we need to make sure these
10*6d481b5dSEd Tanous // are included AFTER the system headers, which are implictly included by boost.
11*6d481b5dSEd Tanous // These show up as errors like
12*6d481b5dSEd Tanous // /usr/include/net/if.h:44:14: error: ‘IFF_UP’ conflicts with a previous
13*6d481b5dSEd Tanous // declaration
14*6d481b5dSEd Tanous // The bugs below are other projects working around similar issues
15*6d481b5dSEd Tanous // https://bugzilla.redhat.com/show_bug.cgi?id=1300256
16*6d481b5dSEd Tanous // https://github.com/systemd/systemd/commit/08ce521fb2546921f2642bef067d2cc02158b121
17*6d481b5dSEd Tanous // https://github.com/systemd/systemd/issues/2864
18*6d481b5dSEd Tanous // clang-format off
19*6d481b5dSEd Tanous #include <linux/mctp.h>
20*6d481b5dSEd Tanous #include <sys/socket.h>
21*6d481b5dSEd Tanous // clang-format on
22*6d481b5dSEd Tanous 
23*6d481b5dSEd Tanous // Wrapper around boost::asio::generic::datagram_protocol::endpoint to provide
24*6d481b5dSEd Tanous // MCTP specific APIs that are available to the kernel
25*6d481b5dSEd Tanous struct MctpAsioEndpoint
26*6d481b5dSEd Tanous {
27*6d481b5dSEd Tanous     MctpAsioEndpoint() = default;
28*6d481b5dSEd Tanous     MctpAsioEndpoint(const MctpAsioEndpoint&) = delete;
29*6d481b5dSEd Tanous     MctpAsioEndpoint(MctpAsioEndpoint&&) = delete;
30*6d481b5dSEd Tanous     MctpAsioEndpoint& operator=(const MctpAsioEndpoint&) = delete;
31*6d481b5dSEd Tanous     MctpAsioEndpoint& operator=(MctpAsioEndpoint&&) = delete;
32*6d481b5dSEd Tanous 
33*6d481b5dSEd Tanous     boost::asio::generic::datagram_protocol::endpoint endpoint;
34*6d481b5dSEd Tanous 
eidMctpAsioEndpoint35*6d481b5dSEd Tanous     std::optional<uint8_t> eid() const
36*6d481b5dSEd Tanous     {
37*6d481b5dSEd Tanous         const struct sockaddr_mctp* sock = getSockAddr();
38*6d481b5dSEd Tanous         if (sock == nullptr)
39*6d481b5dSEd Tanous         {
40*6d481b5dSEd Tanous             return std::nullopt;
41*6d481b5dSEd Tanous         }
42*6d481b5dSEd Tanous         return sock->smctp_addr.s_addr;
43*6d481b5dSEd Tanous     }
44*6d481b5dSEd Tanous 
typeMctpAsioEndpoint45*6d481b5dSEd Tanous     std::optional<uint8_t> type() const
46*6d481b5dSEd Tanous     {
47*6d481b5dSEd Tanous         const struct sockaddr_mctp* sock = getSockAddr();
48*6d481b5dSEd Tanous         if (sock == nullptr)
49*6d481b5dSEd Tanous         {
50*6d481b5dSEd Tanous             return std::nullopt;
51*6d481b5dSEd Tanous         }
52*6d481b5dSEd Tanous         return sock->smctp_type;
53*6d481b5dSEd Tanous     }
54*6d481b5dSEd Tanous 
55*6d481b5dSEd Tanous   private:
getSockAddrMctpAsioEndpoint56*6d481b5dSEd Tanous     const struct sockaddr_mctp* getSockAddr() const
57*6d481b5dSEd Tanous     {
58*6d481b5dSEd Tanous         if (endpoint.size() < sizeof(struct sockaddr_mctp))
59*6d481b5dSEd Tanous         {
60*6d481b5dSEd Tanous             lg2::error("MctpRequester: Received endpoint is too small?");
61*6d481b5dSEd Tanous             return nullptr;
62*6d481b5dSEd Tanous         }
63*6d481b5dSEd Tanous 
64*6d481b5dSEd Tanous         return std::bit_cast<struct sockaddr_mctp*>(endpoint.data());
65*6d481b5dSEd Tanous     }
66*6d481b5dSEd Tanous };
67