2016-08-02 01:17:41 +00:00
//
// 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/>.
//
# include <uhd/rfnoc/node_ctrl_base.hpp>
# include <uhd/utils/msg.hpp>
2016-09-29 21:23:50 +00:00
# include <boost/range/adaptor/map.hpp>
2016-08-02 01:17:41 +00:00
using namespace uhd : : rfnoc ;
std : : string node_ctrl_base : : unique_id ( ) const
{
// Most instantiations will override this, so we don't need anything
// more elegant here.
return str ( boost : : format ( " %08X " ) % size_t ( this ) ) ;
}
void node_ctrl_base : : clear ( )
{
UHD_RFNOC_BLOCK_TRACE ( ) < < " node_ctrl_base::clear() " < < std : : endl ;
// Reset connections:
_upstream_nodes . clear ( ) ;
_downstream_nodes . clear ( ) ;
}
void node_ctrl_base : : _register_downstream_node (
node_ctrl_base : : sptr ,
size_t
) {
throw uhd : : runtime_error ( " Attempting to register a downstream block on a non-source node. " ) ;
}
void node_ctrl_base : : _register_upstream_node (
node_ctrl_base : : sptr ,
size_t
) {
throw uhd : : runtime_error ( " Attempting to register an upstream block on a non-sink node. " ) ;
}
void node_ctrl_base : : set_downstream_port (
const size_t this_port ,
const size_t remote_port
) {
if ( not _downstream_nodes . count ( this_port ) and remote_port ! = ANY_PORT ) {
throw uhd : : value_error ( str (
boost : : format ( " [%s] Cannot set remote downstream port: Port %d not connected. " )
% unique_id ( ) % this_port
) ) ;
}
_downstream_ports [ this_port ] = remote_port ;
}
size_t node_ctrl_base : : get_downstream_port ( const size_t this_port )
{
if ( not _downstream_ports . count ( this_port )
or not _downstream_nodes . count ( this_port )
or _downstream_ports [ this_port ] = = ANY_PORT ) {
throw uhd : : value_error ( str (
boost : : format ( " [%s] Cannot retrieve remote downstream port: Port %d not connected. " )
% unique_id ( ) % this_port
) ) ;
}
return _downstream_ports [ this_port ] ;
}
void node_ctrl_base : : set_upstream_port (
const size_t this_port ,
const size_t remote_port
) {
if ( not _upstream_nodes . count ( this_port ) and remote_port ! = ANY_PORT ) {
throw uhd : : value_error ( str (
boost : : format ( " [%s] Cannot set remote upstream port: Port %d not connected. " )
% unique_id ( ) % this_port
) ) ;
}
_upstream_ports [ this_port ] = remote_port ;
}
size_t node_ctrl_base : : get_upstream_port ( const size_t this_port )
{
if ( not _upstream_ports . count ( this_port )
or not _upstream_nodes . count ( this_port )
or _upstream_ports [ this_port ] = = ANY_PORT ) {
throw uhd : : value_error ( str (
boost : : format ( " [%s] Cannot retrieve remote upstream port: Port %d not connected. " )
% unique_id ( ) % this_port
) ) ;
}
return _upstream_ports [ this_port ] ;
}
2016-09-29 21:23:50 +00:00
void node_ctrl_base : : disconnect ( )
{
// Notify neighbours:
for ( node_map_t : : iterator i = _downstream_nodes . begin ( ) ; i ! = _downstream_nodes . end ( ) ; + + i ) {
sptr downstream_node = i - > second . lock ( ) ;
if ( not downstream_node ) {
// Actually this is not OK
continue ;
}
downstream_node - > disconnect_input_port ( _downstream_ports [ i - > first ] ) ;
}
for ( node_map_t : : iterator i = _upstream_nodes . begin ( ) ; i ! = _upstream_nodes . end ( ) ; + + i ) {
sptr upstream_node = i - > second . lock ( ) ;
if ( not upstream_node ) {
// Actually this is not OK
continue ;
}
upstream_node - > disconnect_output_port ( _upstream_ports [ i - > first ] ) ;
}
// Clear own maps:
_downstream_nodes . clear ( ) ;
_downstream_ports . clear ( ) ;
_upstream_nodes . clear ( ) ;
_upstream_ports . clear ( ) ;
}
void node_ctrl_base : : disconnect_output_port ( const size_t output_port )
{
if ( _downstream_nodes . count ( output_port ) = = 0 or
_downstream_ports . count ( output_port ) = = 0 ) {
throw uhd : : assertion_error ( str ( boost : : format ( " [%s] Attempting to disconnect output port %u, which is not registered as connected! " ) % unique_id ( ) % output_port ) ) ;
}
_downstream_nodes . erase ( output_port ) ;
_downstream_ports . erase ( output_port ) ;
}
void node_ctrl_base : : disconnect_input_port ( const size_t input_port )
{
if ( _upstream_nodes . count ( input_port ) = = 0 or
_upstream_ports . count ( input_port ) = = 0 ) {
throw uhd : : assertion_error ( str ( boost : : format ( " [%s] Attempting to disconnect input port %u, which is not registered as connected! " ) % unique_id ( ) % input_port ) ) ;
}
_upstream_nodes . erase ( input_port ) ;
_upstream_ports . erase ( input_port ) ;
}