diff options
author | Michael West <michael.west@ettus.com> | 2018-08-23 17:09:00 -0700 |
---|---|---|
committer | Brent Stapleton <bstapleton@g.hmc.edu> | 2018-10-25 09:57:16 -0700 |
commit | adfd3d9598eb23751cd9a7a53acce6c16261e828 (patch) | |
tree | 959cbfcc71f82615ef0094908c1239c33c75880e | |
parent | 1256821f3e61ec677cd4b4e75be14f0f376f5215 (diff) | |
download | uhd-adfd3d9598eb23751cd9a7a53acce6c16261e828.tar.gz uhd-adfd3d9598eb23751cd9a7a53acce6c16261e828.tar.bz2 uhd-adfd3d9598eb23751cd9a7a53acce6c16261e828.zip |
X300: Prevent duplicate MAC and IP addresses from being programmed in MB
EEPROM
-rw-r--r-- | host/lib/include/uhdlib/utils/eeprom_utils.hpp | 80 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_mb_eeprom.cpp | 26 |
2 files changed, 104 insertions, 2 deletions
diff --git a/host/lib/include/uhdlib/utils/eeprom_utils.hpp b/host/lib/include/uhdlib/utils/eeprom_utils.hpp index 28deca790..3071fd745 100644 --- a/host/lib/include/uhdlib/utils/eeprom_utils.hpp +++ b/host/lib/include/uhdlib/utils/eeprom_utils.hpp @@ -5,8 +5,10 @@ // #include <uhd/types/byte_vector.hpp> +#include <uhd/types/dict.hpp> #include <uhd/types/mac_addr.hpp> #include <boost/asio/ip/address_v4.hpp> +#include <uhd/utils/log.hpp> #include <string> #include <vector> @@ -18,3 +20,81 @@ uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str); //! convert a byte vector read from eeprom to a string std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes); + +/*! + * Check for duplicate values within a given set of keys. Assumes the desire + * is to replace current EEPROM contents with new EEPROM contents and checks to + * see if the resulting contents will contain duplicates. Useful error + * messages are logged describing any duplicates. + * + * <field_type> must provide to_string() and from_string() functions + * + * \param error_label Label to put on error messages + * \param new_eeprom New EEPROM contents + * \param curr_eeprom Current EEPROM contents + * \param category Category label for the type of values being checked + * \param keys Keys to examine for duplicate values + * \return true if duplicates are found, false if not + */ +template <typename field_type> +bool check_for_duplicates( + const std::string& error_label, + const uhd::dict<std::string, std::string>& new_eeprom, + const uhd::dict<std::string, std::string>& curr_eeprom, + const std::string& category, + const std::vector<std::string>& keys +) { + bool has_duplicates = false; + for (size_t i = 0; i < keys.size(); i++) + { + bool found_duplicate = false; + auto key = keys[i]; + + if (not new_eeprom.has_key(key)) + { + continue; + } + + auto value = field_type::from_string(new_eeprom[key]).to_string(); + + // Check other values in new_eeprom for duplicate + // Starting at key index i+1 so the same duplicate is not found twice + for (size_t j = i+1; j < keys.size(); j++) + { + auto other_key = keys[j]; + if (not new_eeprom.has_key(other_key)) + { + continue; + } + auto other_value = field_type::from_string(new_eeprom[other_key]).to_string(); + if (value == other_value) + { + // Value is a duplicate of another supplied value + UHD_LOG_ERROR(error_label, "Duplicate " << category << " " + << new_eeprom[key] << " is supplied for both " << key + << " and " << other_key); + found_duplicate = true; + } + } + // Check all keys in curr_eeprom for duplicate value + for (auto other_key: keys) + { + // Skip any keys in new_eeprom + if (new_eeprom.has_key(other_key)) + { + continue; + } + + if (value == curr_eeprom[other_key]) + { + // Value is duplicate of one in the EEPROM + UHD_LOG_ERROR(error_label, "Duplicate " << category << " " + << new_eeprom[key] << " is already in use for " + << other_key); + found_duplicate = true; + } + } + has_duplicates |= found_duplicate; + } + return has_duplicates; +} diff --git a/host/lib/usrp/x300/x300_mb_eeprom.cpp b/host/lib/usrp/x300/x300_mb_eeprom.cpp index b8fb59538..7bff3d782 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom.cpp +++ b/host/lib/usrp/x300/x300_mb_eeprom.cpp @@ -130,11 +130,34 @@ mboard_eeprom_t x300_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) return mb_eeprom; } - void x300_impl::set_mb_eeprom( i2c_iface::sptr iface, const mboard_eeprom_t &mb_eeprom ) { + const mboard_eeprom_t curr_eeprom = get_mb_eeprom(iface); + + // Check for duplicate MAC and IP addresses + const std::vector<std::string> mac_keys{ + "mac-addr0", + "mac-addr1" + }; + const std::vector<std::string> ip_keys{ + "ip-addr0", + "ip-addr1", + "ip-addr2", + "ip-addr3" + }; + + //make sure there are no duplicate values + if (check_for_duplicates<uhd::mac_addr_t>( + "X300", mb_eeprom, curr_eeprom,"MAC address", mac_keys) or + check_for_duplicates<boost::asio::ip::address_v4>( + "X300", mb_eeprom, curr_eeprom, "IP address", ip_keys)) + { + throw uhd::value_error( + "Duplicate values not permitted - write to EEPROM aborted"); + } + //parse the revision number if (mb_eeprom.has_key("revision")) iface->write_eeprom( X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision), @@ -195,4 +218,3 @@ void x300_impl::set_mb_eeprom( string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) ); } - |