aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
blob: 4b0ba4212261887de9909b13c1f97acd37d010b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
// Copyright 2017 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifndef INCLUDED_MPMD_LINK_IF_MGR_HPP
#define INCLUDED_MPMD_LINK_IF_MGR_HPP

#include <uhd/types/device_addr.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/direction.hpp>
#include <uhdlib/rfnoc/chdr_packet.hpp>
#include <uhdlib/transport/links.hpp>
#include <map>
#include <memory>
#include <string>
#include <vector>

namespace uhd { namespace mpmd { namespace xport {

/*
 * Transport specifiers
 */

//! Primary Ethernet address for streaming and RFNoC communication
const std::string FIRST_ADDR_KEY = "addr";
//! Secondary Ethernet address for streaming and RFNoC communication
const std::string SECOND_ADDR_KEY = "second_addr";

/*! Return filtered subset from a device_addr_t
 *
 * The return dictionary will contain all key/value pairs from \p args
 * where the key begins with \p prefix.
 *
 * \param args Bucket of key/value pairs
 * \param prefix Key prefix to match against
 */
uhd::dict<std::string, std::string> filter_args(
    const uhd::device_addr_t& args, const std::string& prefix);

/*! MPMD Transport Manager
 *
 * A transport manager is an object which sets up a physical connection to a
 * CHDR device. Its implementation is specific to the underlying transport
 * medium. For example, if the medium is Ethernet/UDP, this class will create
 * sockets.
 */
class mpmd_link_if_mgr
{
public:
    using uptr              = std::unique_ptr<mpmd_link_if_mgr>;
    using xport_info_t      = std::map<std::string, std::string>;
    using xport_info_list_t = std::vector<std::map<std::string, std::string>>;
    virtual ~mpmd_link_if_mgr() {}

    /*! Return a reference to a transport manager
     *
     * \param mb_args Additional args from the motherboard. These may contain
     *                transport-related args (e.g., "recv_buff_size") which
     *                can be relevant to the underlying implementation.
     *
     * \returns Reference to manager object
     * \throws uhd::key_error if \p xport_medium is not supported. The ctor of
     *         the underlying class that is requested can also throw.
     */
    static uptr make(const uhd::device_addr_t& mb_args);

    /*! Attempt to open a CHDR-capable link to the remote device
     *
     * This will compare the mb_args (passed in at construction) with
     * \p xport_info to see if it can connect this way. For example, if
     * \p xport_type is "udp", then it will see if it can find the `addr` key
     * from mb_args in the \p xport_info. If yes, it will use that for
     * connections.
     *
     * \param xport_type The type of xport ("udp", "liberio", ...)
     * \param xport_info The available information on this transport. For
     *                   example, if the xport_type is "udp", then this would
     *                   contain the available IP addresses.
     * \returns true on success
     */
    virtual bool connect(
        const std::string& xport_type, const xport_info_list_t& xport_info) = 0;

    /*! The number of available links
     *
     * If zero, it means that there is no valid connection to the device.
     *
     */
    virtual size_t get_num_links() = 0;

    /*! Return links object
     *
     * \param link_idx The number of the link to use. link_idx < get_num_links()
     *                 must hold true. link_idx is often 0. Example: When
     *                 the underlying transport is Ethernet, and the user
     *                 specified both addr and second_addr, then get_num_links()
     *                 equals 2 and link_idx can also be 1.
     * \param link_type CTRL, RX_DATA, or TX_DATA (for configuring the link)
     * \param link_args Link-specific additional information that the underlying
     *                  mpmd_link_if_ctrl instantiation can use
     */
    virtual uhd::transport::both_links_t get_link(const size_t link_idx,
        const uhd::transport::link_type_t link_type,
        const uhd::device_addr_t& link_args) = 0;

    /*! Create a transports object
     *
     * Implementation details depend on the underlying implementation.
     * In general, the implementations will follow the following recipe:
     * 1. Pick a suitable element from \p xport_info_list
     * 2. Do whatever system calls are necessary to create the physical
     *    transport; to do so, call the underlying implementation (UDP or
     *    whatever)
     * 3. Update the selected element from xport_info_list
     * 5. Return results
     *
     * \param xport_info_list List of possible options to choose from. Every
     *                        element of this argument needs to have the same
     *                        "type" key (e.g., they all need to be "UDP").
     * \param xport_type Transport type (CTRL, RX_DATA, ...)
     * \param xport_args Arbitrary additional transport args. These could come
     *                   from the user, or other places.
     * \param xport_info_out The updated dictionary from xport_info_list that
     *                       was eventually chosen
     *
     * \returns The both_xports_t object containing the actual transport info,
     *          and xport_info_out contains the updated transport option info.
     *          The latter needs to get sent back to MPM to complete the
     *          transport handshake.
     */
    //virtual both_xports_t make_transport(const xport_info_list_t& xport_info_list,
        //const usrp::device3_impl::xport_type_t xport_type,
        //const uhd::device_addr_t& xport_args,
        //xport_info_t& xport_info_out) = 0;

    /*! Return the path MTU for whatever this manager lets us do
     */
    virtual size_t get_mtu(const size_t link_idx, const uhd::direction_t dir) const = 0;

    /*! Get packet factory from associated link_mgr
     *
     * \param link_idx The number of the link to use. link_idx < get_num_links()
     *                 must hold true. link_idx is often 0. Example: When
     *                 the underlying transport is Ethernet, and the user
     *                 specified both addr and second_addr, then get_num_links()
     *                 equals 2 and link_idx can also be 1.
     * \return a CHDR packet factory
     */
    virtual const uhd::rfnoc::chdr::chdr_packet_factory& get_packet_factory(
        const size_t link_idx) const = 0;
};

}}} /* namespace uhd::mpmd::xport */

#endif /* INCLUDED_MPMD_LINK_IF_MGR_HPP */