1 //
2 // Copyright 2011 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7
8 #include <uhd/exception.hpp>
9 #include <uhd/utils/assert_has.hpp>
10 #include <uhdlib/usrp/common/validate_subdev_spec.hpp>
11 #include <boost/format.hpp>
12
13 using namespace uhd;
14 using namespace uhd::usrp;
15
16 namespace uhd { namespace usrp {
17
operator <<(std::ostream & out,const subdev_spec_pair_t & pair)18 static std::ostream& operator<<(std::ostream& out, const subdev_spec_pair_t& pair)
19 {
20 out << pair.db_name << ":" << pair.sd_name;
21 return out;
22 }
23
24 }} // namespace uhd::usrp
25
validate_subdev_spec(property_tree::sptr tree,const subdev_spec_t & spec,const std::string & type,const std::string & mb)26 void uhd::usrp::validate_subdev_spec(property_tree::sptr tree,
27 const subdev_spec_t& spec,
28 const std::string& type,
29 const std::string& mb)
30 {
31 const size_t num_dsps =
32 tree->list(str(boost::format("/mboards/%s/%s_dsps") % mb % type)).size();
33
34 // sanity checking on the length
35 if (spec.size() == 0)
36 throw uhd::value_error(
37 str(boost::format("Empty %s subdevice specification is not supported.\n")
38 % type));
39 if (spec.size() > num_dsps)
40 throw uhd::value_error(
41 str(boost::format("The subdevice specification \"%s\" is too long.\n"
42 "The user specified %u channels, but there are only %u %s "
43 "dsps on mboard %s.\n")
44 % spec.to_string() % spec.size() % num_dsps % type % mb));
45
46 // make a list of all possible specs
47 subdev_spec_t all_specs;
48 for (const std::string& db :
49 tree->list(str(boost::format("/mboards/%s/dboards") % mb))) {
50 for (const std::string& sd :
51 tree->list(str(
52 boost::format("/mboards/%s/dboards/%s/%s_frontends") % mb % db % type))) {
53 all_specs.push_back(subdev_spec_pair_t(db, sd));
54 }
55 }
56
57 // validate that the spec is possible
58 for (const subdev_spec_pair_t& pair : spec) {
59 uhd::assert_has(all_specs,
60 pair,
61 str(boost::format("%s subdevice specification on mboard %s") % type % mb));
62 }
63
64 // enable selected frontends, disable others
65 for (const subdev_spec_pair_t& pair : all_specs) {
66 const bool enb = uhd::has(spec, pair);
67 tree->access<bool>(
68 str(boost::format("/mboards/%s/dboards/%s/%s_frontends/%s/enabled") % mb
69 % pair.db_name % type % pair.sd_name))
70 .set(enb);
71 }
72 }
73