1 //
2 // Copyright 2014 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 // Copyright 2019 Ettus Research, A National Instruments Brand
5 //
6 // SPDX-License-Identifier: GPL-3.0-or-later
7 //
8
9 #include <uhd/exception.hpp>
10 #include <uhd/property_tree.hpp>
11 #include <uhd/rfnoc/block_id.hpp>
12 #include <uhd/rfnoc/constants.hpp>
13 #include <boost/format.hpp>
14 #include <boost/lexical_cast.hpp>
15 #include <iostream>
16 #include <regex>
17
18 using namespace uhd::rfnoc;
19
block_id_t()20 block_id_t::block_id_t() : _device_no(0), _block_name(""), _block_ctr(0) {}
21
block_id_t(const std::string & block_str)22 block_id_t::block_id_t(const std::string& block_str)
23 : _device_no(0), _block_name(""), _block_ctr(0)
24 {
25 if (not set(block_str)) {
26 throw uhd::value_error(
27 "block_id_t: Invalid block ID string: `" + block_str + "'");
28 }
29 }
30
block_id_t(const size_t device_no,const std::string & block_name,const size_t block_ctr)31 block_id_t::block_id_t(
32 const size_t device_no, const std::string& block_name, const size_t block_ctr)
33 : _device_no(device_no), _block_name(block_name), _block_ctr(block_ctr)
34 {
35 if (not is_valid_blockname(block_name)) {
36 throw uhd::value_error("block_id_t: Invalid block name.");
37 }
38 }
39
is_valid_blockname(const std::string & block_name)40 bool block_id_t::is_valid_blockname(const std::string& block_name)
41 {
42 return std::regex_match(block_name, std::regex(VALID_BLOCKNAME_REGEX));
43 }
44
is_valid_block_id(const std::string & block_name)45 bool block_id_t::is_valid_block_id(const std::string& block_name)
46 {
47 return std::regex_match(block_name, std::regex(VALID_BLOCKID_REGEX));
48 }
49
to_string() const50 std::string block_id_t::to_string() const
51 {
52 return str(boost::format("%d/%s") % get_device_no() % get_local());
53 }
54
get_local() const55 std::string block_id_t::get_local() const
56 {
57 return str(boost::format("%s#%d") % get_block_name() % get_block_count());
58 }
59
get_tree_root() const60 uhd::fs_path block_id_t::get_tree_root() const
61 {
62 return str(boost::format("/mboards/%d/xbar/%s") % get_device_no() % get_local());
63 }
64
match(const std::string & block_str)65 bool block_id_t::match(const std::string& block_str)
66 {
67 std::cmatch matches;
68 if (not std::regex_match(
69 block_str.c_str(), matches, std::regex(VALID_BLOCKID_REGEX))) {
70 return false;
71 }
72 try {
73 return (matches[1] == "" or boost::lexical_cast<size_t>(matches[1]) == _device_no)
74 and (matches[2] == "" or matches[2] == _block_name)
75 and (matches[3] == ""
76 or boost::lexical_cast<size_t>(matches[3]) == _block_ctr)
77 and not(matches[1] == "" and matches[2] == "" and matches[3] == "");
78 } catch (const std::bad_cast&) {
79 return false;
80 }
81 return false;
82 }
83
set(const std::string & new_name)84 bool block_id_t::set(const std::string& new_name)
85 {
86 std::cmatch matches;
87 if (not std::regex_match(
88 new_name.c_str(), matches, std::regex(VALID_BLOCKID_REGEX))) {
89 return false;
90 }
91 if (not(matches[1] == "")) {
92 _device_no = boost::lexical_cast<size_t>(matches[1]);
93 }
94 if (not(matches[2] == "")) {
95 _block_name = matches[2];
96 }
97 if (not(matches[3] == "")) {
98 _block_ctr = boost::lexical_cast<size_t>(matches[3]);
99 }
100 return true;
101 }
102
set(const size_t device_no,const std::string & block_name,const size_t block_ctr)103 bool block_id_t::set(
104 const size_t device_no, const std::string& block_name, const size_t block_ctr)
105 {
106 if (not set_block_name(block_name)) {
107 return false;
108 }
109 set_device_no(device_no);
110 set_block_count(block_ctr);
111 return true;
112 }
113
set_block_name(const std::string & block_name)114 bool block_id_t::set_block_name(const std::string& block_name)
115 {
116 if (not is_valid_blockname(block_name)) {
117 return false;
118 }
119 _block_name = block_name;
120 return true;
121 }
122