aboutsummaryrefslogtreecommitdiffstats
path: root/host/include/uhd/rfnoc/source_node_ctrl.hpp
blob: a351f6c8e7fdb879659a7cc55cbd6d1c3cabb7a3 (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
//
// Copyright 2014 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP
#define INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP

#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/rfnoc/constants.hpp>
#include <uhd/types/stream_cmd.hpp>
#include <boost/thread.hpp>

namespace uhd {
    namespace rfnoc {

/*! \brief Abstract class for source nodes.
 *
 * Source nodes can have downstream blocks.
 */
class UHD_RFNOC_API source_node_ctrl;
class source_node_ctrl : virtual public node_ctrl_base
{
public:
    /***********************************************************************
     * Types
     **********************************************************************/
    typedef boost::shared_ptr<source_node_ctrl> sptr;
    typedef std::map< size_t, boost::weak_ptr<source_node_ctrl> > node_map_t;
    typedef std::pair< size_t, boost::weak_ptr<source_node_ctrl> > node_map_pair_t;

    /***********************************************************************
     * Source block controls
     **********************************************************************/
    /*! Issue a stream command for this block.
     * \param stream_cmd The stream command.
     * \param chan Channel Index
     */
    virtual void issue_stream_cmd(
        const uhd::stream_cmd_t &stream_cmd,
        const size_t chan=0
    ) = 0;

    /*! Connect another node downstream of this node.
     *
     * *Note:* If additional settings are required to make this connection work,
     * e.g. configure flow control, these need to be done separately.
     *
     * If the requested connection is not possible, this function will throw.
     *
     * \p downstream_node Pointer to the node class to connect
     * \p port Suggested port number on this block to connect the downstream
     *         block to.
     * \p args Any arguments that can be useful for determining the port number.
     *
     * \returns The actual port number used.
     */
    size_t connect_downstream(
            node_ctrl_base::sptr downstream_node,
            size_t port=ANY_PORT,
            const uhd::device_addr_t &args=uhd::device_addr_t()
    );

    /*! Call this function to notify a node about its streamer activity.
     *
     * When \p active is set to true, this means this block is now part of
     * an active rx streamer chain. Conversely, when set to false, this means
     * the node has been removed from an rx streamer chain.
     */
    virtual void set_rx_streamer(bool active, const size_t port);

protected:

    /*! For every output port, store rx streamer activity.
     *
     * If _rx_streamer_active[0] == true, this means that an active rx
     * streamer is operating on port 0. If it is false, or if the entry
     * does not exist, there is no streamer.
     * Values are toggled by set_rx_streamer().
     */
    std::map<size_t, bool> _rx_streamer_active;

    /*! Ask for a port number to connect a downstream block to.
     *
     * See sink_node_ctrl::_request_input_port(). This is the same
     * for output.
     *
     * \param suggested_port Try and connect here.
     * \param args When deciding on a port number, these arguments may be used.
     *
     * \returns A valid input port, or ANY_PORT on failure.
     */
    virtual size_t _request_output_port(
            const size_t suggested_port,
            const uhd::device_addr_t &args
    ) const;


private:
    /*! Makes connecting something to the output thread-safe.
     */
    boost::mutex _output_mutex;

    /*! Register a node downstream of this one (i.e., a node that receives data from this node).
     *
     * By definition, the upstream node must of type sink_node_ctrl.
     *
     * This saves a *weak pointer* to the downstream node and checks
     * the port is available. Will throw otherwise.
     *
     * \param downstream_node A pointer to the node instantiation
     * \param port Port number the downstream node is connected to
     */
    void _register_downstream_node(
            node_ctrl_base::sptr downstream_node,
            size_t port
    );

}; /* class source_node_ctrl */

}} /* namespace uhd::rfnoc */

#endif /* INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP */
// vim: sw=4 et: