aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2015-01-28 22:10:10 +0100
committerMartin Braun <martin.braun@ettus.com>2015-01-28 22:10:10 +0100
commitdb3fac73beb30ceaaf6a275d9668a38af3b839f5 (patch)
treed0713571a7a4d14d38c4d6c59337e6fbfca1f4a1
parent156c21206e8bccf4b5680a62c28a7dc7544aa9be (diff)
parent75d519706b9b0956307a6a4bdc53c36376f19f03 (diff)
downloaduhd-db3fac73beb30ceaaf6a275d9668a38af3b839f5.tar.gz
uhd-db3fac73beb30ceaaf6a275d9668a38af3b839f5.tar.bz2
uhd-db3fac73beb30ceaaf6a275d9668a38af3b839f5.zip
Merge paths-fix branch into maint.
-rw-r--r--host/CMakeLists.txt22
-rw-r--r--host/docs/images.dox6
-rw-r--r--host/include/uhd/config.hpp12
-rw-r--r--host/include/uhd/transport/nirio/nifpga_lvbitx.h2
-rw-r--r--host/include/uhd/utils/CMakeLists.txt1
-rw-r--r--host/include/uhd/utils/images.hpp53
-rw-r--r--host/include/uhd/utils/paths.hpp58
-rw-r--r--host/lib/transport/nirio/lvbitx/CMakeLists.txt7
-rw-r--r--host/lib/transport/nirio/lvbitx/template_lvbitx.cpp6
-rw-r--r--host/lib/transport/nirio/nifpga_lvbitx.cpp103
-rw-r--r--host/lib/usrp/b100/b100_impl.cpp10
-rw-r--r--host/lib/usrp/b100/b100_impl.hpp2
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp24
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp6
-rw-r--r--host/lib/usrp/e100/e100_impl.cpp4
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp4
-rw-r--r--host/lib/usrp/e300/e300_network.cpp2
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp4
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp8
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp14
-rw-r--r--host/lib/usrp_clock/octoclock/octoclock_impl.cpp6
-rw-r--r--host/lib/utils/CMakeLists.txt1
-rw-r--r--host/lib/utils/images.cpp54
-rw-r--r--host/lib/utils/load_modules.cpp5
-rw-r--r--host/lib/utils/paths.cpp306
-rw-r--r--host/utils/b2xx_fx3_utils.cpp2
-rw-r--r--host/utils/octoclock_firmware_burner.cpp2
-rw-r--r--host/utils/usrp_n2xx_simple_net_burner.cpp2
-rw-r--r--host/utils/usrp_x3xx_fpga_burner.cpp2
29 files changed, 416 insertions, 312 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index c90c5de14..4a6c171f5 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -60,6 +60,26 @@ SET(PKG_DOC_DIR share/doc/uhd)
SET(PKG_MAN_DIR share/man/man1)
########################################################################
+# UHD Image Directories
+########################################################################
+IF(NOT DEFINED UHD_IMAGES_DIR)
+ IF(DEFINED FPGA_IMAGES_DIR)
+ SET(UHD_IMAGES_DIR ${FPGA_IMAGES_DIR})
+ ELSE(DEFINED FPGA_IMAGES_DIR)
+ FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/share/uhd/images using_images_dir)
+ SET(UHD_IMAGES_DIR ${using_images_dir})
+ ENDIF(DEFINED FPGA_IMAGES_DIR)
+ENDIF(NOT DEFINED UHD_IMAGES_DIR)
+
+OPTION(UHD_IMAGES_DIR "Path to installed UHD image binaries.")
+MESSAGE( STATUS "Using UHD Images Directory: ${UHD_IMAGES_DIR}" )
+ADD_DEFINITIONS(-DUHD_IMAGES_DIR=${UHD_IMAGES_DIR})
+
+IF(DEFINED USE_NIUSRP_WINREG_KEY)
+ ADD_DEFINITIONS(-DUSE_NIUSRP_WINREG_KEY)
+ENDIF(DEFINED USE_NIUSRP_WINREG_KEY)
+
+########################################################################
# Local Include Dir
########################################################################
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
@@ -362,7 +382,7 @@ UHD_INSTALL(
)
########################################################################
-# Handle pre-built images
+# Handle pre-built UHD Images meant for installation
########################################################################
IF(DEFINED UHD_IMAGES_DIR AND EXISTS "${UHD_IMAGES_DIR}")
FILE(GLOB_RECURSE _image_files "${UHD_IMAGES_DIR}/*")
diff --git a/host/docs/images.dox b/host/docs/images.dox
index e00f599b5..bd2ffacf6 100644
--- a/host/docs/images.dox
+++ b/host/docs/images.dox
@@ -65,9 +65,9 @@ configure-time.
<b>Option 2:</b>
-Unpack the archive anywhere and set the `UHD_IMAGES_PATH`
-environment variable. `UHD_IMAGES_PATH` may contain a list of
-directories to search for image files.
+Unpack the archive anywhere and set the `UHD_IMAGES_DIR` environment variable.
+The `UHD_IMAGES_DIR` environment variable may contain a list of paths. They
+should be ordered by preference.
\section images_building Building Images
diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp
index 619bd0787..7ecc4924a 100644
--- a/host/include/uhd/config.hpp
+++ b/host/include/uhd/config.hpp
@@ -92,4 +92,16 @@ typedef ptrdiff_t ssize_t;
#define UHD_PLATFORM_BSD
#endif
+// Define 'stringize' preprocessor macros. The stringize macro, XSTR, takes
+// variable arguments so that it can deal with strings that contain commas.
+// There are two different versions because MSVC handles this syntax a bit
+// differently than other compilers.
+#if defined(BOOST_MSVC)
+ #define XSTR(x,...) #x
+#else
+ #define XSTR(x...) #x
+#endif
+
+#define STR(x) XSTR(x)
+
#endif /* INCLUDED_UHD_CONFIG_HPP */
diff --git a/host/include/uhd/transport/nirio/nifpga_lvbitx.h b/host/include/uhd/transport/nirio/nifpga_lvbitx.h
index 598f7fcbe..f037ffd47 100644
--- a/host/include/uhd/transport/nirio/nifpga_lvbitx.h
+++ b/host/include/uhd/transport/nirio/nifpga_lvbitx.h
@@ -51,8 +51,8 @@ public:
protected:
std::string _get_bitstream_checksum(const std::string& file_path);
- std::string _get_fpga_images_dir(const std::string search_paths);
};
+
}}
#endif /* INCLUDED_UHD_TRANSPORT_NIRIO_NIFPGA_LVBITX_H */
diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt
index c308c9cde..05f6892d2 100644
--- a/host/include/uhd/utils/CMakeLists.txt
+++ b/host/include/uhd/utils/CMakeLists.txt
@@ -25,7 +25,6 @@ UHD_INSTALL(FILES
cast.hpp
csv.hpp
gain_group.hpp
- images.hpp
log.hpp
math.hpp
msg.hpp
diff --git a/host/include/uhd/utils/images.hpp b/host/include/uhd/utils/images.hpp
deleted file mode 100644
index a0934fb08..000000000
--- a/host/include/uhd/utils/images.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright 2010,2012 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_UHD_UTILS_IMAGES_HPP
-#define INCLUDED_UHD_UTILS_IMAGES_HPP
-
-#include <uhd/config.hpp>
-#include <string>
-
-namespace uhd{
-
- /*!
- * Search for an image in the system image paths:
- * Search compiled-in paths and environment variable paths
- * for a specific image file with the provided file name.
- * \param image_name the name of the file
- * \return the full system path to the file
- * \throw exception if the image was not found
- */
- UHD_API std::string find_image_path(const std::string &image_name);
-
- /*!
- * Search for the location of the UHD Images Downloader script.
- * \return the full system path to uhd_images_downloader.py
- */
-
- UHD_API std::string find_images_downloader(void);
-
- /*!
- * Return the error string for recommending using the UHD Images Downloader.
- * String depends on OS.
- * \return the message suggesting the use of uhd_images_downloader.py
- */
-
- UHD_API std::string print_images_error(void);
-
-} //namespace uhd
-
-#endif /* INCLUDED_UHD_UTILS_IMAGES_HPP */
diff --git a/host/include/uhd/utils/paths.hpp b/host/include/uhd/utils/paths.hpp
index e0f455e92..8edb87546 100644
--- a/host/include/uhd/utils/paths.hpp
+++ b/host/include/uhd/utils/paths.hpp
@@ -19,9 +19,15 @@
#define INCLUDED_UHD_UTILS_PATHS_HPP
#include <uhd/config.hpp>
+
+#include <boost/filesystem.hpp>
+
#include <string>
+#include <vector>
-namespace uhd{
+namespace fs = boost::filesystem;
+
+namespace uhd {
//! Get a string representing the system's temporary directory
UHD_API std::string get_tmp_path(void);
@@ -32,6 +38,56 @@ namespace uhd{
//! Get a string representing the system's pkg directory
UHD_API std::string get_pkg_path(void);
+ //! Get UHD library paths
+ std::vector<fs::path> get_module_paths(void);
+
+ /*! Return the UHD images directory path.
+ *
+ * This function returns the UHD images installation path on this system. The
+ * returned directory path is guaranteed to exist (assuming a valid path is
+ * found). This function will look for a directory that exists using this
+ * order of precedence:
+ *
+ * 1) `UHD_IMAGES_DIR` environment variable
+ * 2) Any paths passed to this function via `search_paths'
+ * 3) UHD package path / share / uhd / images
+ *
+ * The `search_paths` parameter may contain Windows registry keys. If no
+ * directory is found, an empty string is returned.
+ *
+ * \param search_paths A comma-separated list of hints for paths to include.
+ * \returns A path string if one is found, or an empty string on failure.
+ */
+ UHD_API std::string get_images_dir(const std::string search_paths);
+
+ /*! Return the full path to particular UHD binary image.
+ *
+ * This function searches for the passed image name, and returns an absolute
+ * path to it. The returned path is guaranteed to exist. The caller can also
+ * provide a full path to the image in the argument, and this function will
+ * validate it and convert it to an absolute system path.
+ *
+ * \param image_name The name of the file to search for, or the full path.
+ * \param search_paths Hints / paths to use when calling `get_images_dir`
+ * \return the full system path to the file
+ * \throw exception uhd::io_error if the file was not found.
+ */
+ UHD_API std::string find_image_path(const std::string &image_name, const std::string search_paths = "");
+
+ /*!
+ * Search for the location of a particular UHD utility.
+ * The utility must be installed in the `uhd/utils` directory.
+ * \param the name of the utility to search for
+ * \return the full system path to @param
+ */
+ UHD_API std::string find_utility(std::string name);
+
+ /*!
+ * Return an error string recommending the user run the utility.
+ * The error string will include the full path to the utility to run.
+ * \return the message suggesting the use of the named utility.
+ */
+ UHD_API std::string print_utility_error(std::string name);
} //namespace uhd
#endif /* INCLUDED_UHD_UTILS_PATHS_HPP */
diff --git a/host/lib/transport/nirio/lvbitx/CMakeLists.txt b/host/lib/transport/nirio/lvbitx/CMakeLists.txt
index 35cfaa456..b9a2a9f15 100644
--- a/host/lib/transport/nirio/lvbitx/CMakeLists.txt
+++ b/host/lib/transport/nirio/lvbitx/CMakeLists.txt
@@ -27,7 +27,7 @@ MACRO(LIBUHD_LVBITX_GEN_SOURCE_AND_BITSTREAM lvbitx binfile)
ENDIF( ${binfile} STREQUAL "OFF" )
SET(OUTPUT_PATH_OPT --output-src-path=${CMAKE_CURRENT_BINARY_DIR})
- SET(IMAGES_PATH_OPT --uhd-images-path=${FPGA_IMAGES_DIR})
+ SET(IMAGES_PATH_OPT --uhd-images-path=${UHD_IMAGES_DIR})
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${lvbitxprefix}_lvbitx.hpp
@@ -53,11 +53,6 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
MESSAGE(STATUS "")
MESSAGE(STATUS "Processing NI-RIO FPGA LVBITX Bitstreams...")
-FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/share/uhd/images default_images_dir)
-SET( FPGA_IMAGES_DIR ${default_images_dir} CACHE STRING "Path to installed FPGA image files." )
-OPTION( FPGA_IMAGES_DIR "Path to installed FPGA image files." "" )
-MESSAGE( STATUS " LVBITX install directory: ${FPGA_IMAGES_DIR}" )
-
# X300 Stuff
LIBUHD_LVBITX_GEN_SOURCE_AND_BITSTREAM(x300.lvbitx_base OFF)
diff --git a/host/lib/transport/nirio/lvbitx/template_lvbitx.cpp b/host/lib/transport/nirio/lvbitx/template_lvbitx.cpp
index a1899c771..8f1fb6b36 100644
--- a/host/lib/transport/nirio/lvbitx/template_lvbitx.cpp
+++ b/host/lib/transport/nirio/lvbitx/template_lvbitx.cpp
@@ -8,6 +8,7 @@
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
+#include <uhd/utils/paths.hpp>
namespace uhd {{ namespace niusrprio {{
@@ -27,8 +28,9 @@ const char* {lvbitx_classname}_lvbitx::INPUT_FIFOS[] = {{{in_fifo_list}
{lvbitx_classname}_lvbitx::{lvbitx_classname}_lvbitx(const std::string& option)
{{
- boost::filesystem::path fpga_path(_get_fpga_images_dir(SEARCH_PATHS));
- fpga_path /= "usrp_{lvbitx_classname}_fpga_" + option + ".lvbitx";
+ std::string fpga_file = "usrp_{lvbitx_classname}_fpga_" + option + ".lvbitx";
+ boost::filesystem::path fpga_path(uhd::find_image_path(fpga_file, SEARCH_PATHS));
+
_fpga_file_name = fpga_path.string();
_bitstream_checksum = _get_bitstream_checksum(_fpga_file_name);
}}
diff --git a/host/lib/transport/nirio/nifpga_lvbitx.cpp b/host/lib/transport/nirio/nifpga_lvbitx.cpp
index b87d87a8d..8135a4d01 100644
--- a/host/lib/transport/nirio/nifpga_lvbitx.cpp
+++ b/host/lib/transport/nirio/nifpga_lvbitx.cpp
@@ -18,12 +18,8 @@
#include <uhd/transport/nirio/nifpga_lvbitx.h>
#include <cstdlib>
#include <string>
-#include <iostream>
#include <fstream>
#include <streambuf>
-#include <boost/foreach.hpp>
-#include <boost/format.hpp>
-#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
@@ -52,103 +48,4 @@ std::string nifpga_lvbitx::_get_bitstream_checksum(const std::string& file_path)
return checksum;
}
-#ifdef UHD_PLATFORM_WIN32
-#include <windows.h>
-
-std::string _get_path_from_registry(const std::string& registry_key_path)
-{
- boost::smatch reg_key_match;
- //If a substring in the search path is enclosed in [] (square brackets) then it is interpreted as a registry path
- if (not boost::regex_search(registry_key_path, reg_key_match, boost::regex("\\[(.+)\\](.*)", boost::regex::icase)))
- return std::string();
- std::string reg_key_path = std::string(reg_key_match[1].first, reg_key_match[1].second);
- std::string path_suffix = std::string(reg_key_match[2].first, reg_key_match[2].second);
-
- //Split the registry path into parent, key-path and value.
- boost::smatch reg_parent_match;
- if (not boost::regex_search(reg_key_path, reg_parent_match, boost::regex("^(.+?)\\\\(.+)\\\\(.+)$", boost::regex::icase)))
- return std::string();
- std::string reg_parent = std::string(reg_parent_match[1].first, reg_parent_match[1].second);
- std::string reg_path = std::string(reg_parent_match[2].first, reg_parent_match[2].second);
- std::string reg_val_name = std::string(reg_parent_match[3].first, reg_parent_match[3].second);
-
- HKEY hkey_parent = HKEY_LOCAL_MACHINE;
- if (reg_parent == "HKEY_LOCAL_MACHINE") hkey_parent = HKEY_LOCAL_MACHINE;
- else if (reg_parent == "HKEY_CURRENT_USER") hkey_parent = HKEY_CURRENT_USER;
- else if (reg_parent == "HKEY_CLASSES_ROOT") hkey_parent = HKEY_CLASSES_ROOT;
- else if (reg_parent == "HKEY_CURRENT_CONFIG") hkey_parent = HKEY_CURRENT_CONFIG;
- else if (reg_parent == "HKEY_USERS") hkey_parent = HKEY_CURRENT_USER;
-
- TCHAR value_buff[1024];
- DWORD value_buff_size = 1024*sizeof(TCHAR);
-
- //Get a handle to the key location
- HKEY hkey_location;
- if (RegOpenKeyExA(hkey_parent, reg_path.c_str(), NULL, KEY_QUERY_VALUE, &hkey_location) != ERROR_SUCCESS)
- return std::string();
-
- //Query key value
- DWORD dw_type = REG_SZ;
- if(RegQueryValueExA(hkey_location, reg_val_name.c_str(), NULL, &dw_type, (LPBYTE)value_buff, &value_buff_size) == ERROR_SUCCESS) {
- RegCloseKey(hkey_location);
- if (value_buff_size >= 1024*sizeof(TCHAR)) {
- return std::string();
- } else {
- std::string return_value(value_buff, value_buff_size-1); //value_buff_size includes the null terminator
- return_value += path_suffix;
- return return_value;
- }
- } else {
- return std::string();
- }
-}
-
-#endif /*UHD_PLATFORM_WIN32*/
-
-std::string nifpga_lvbitx::_get_fpga_images_dir(const std::string search_paths)
-{
- std::vector<std::string> search_path_vtr;
- boost::split(search_path_vtr, search_paths, boost::is_any_of(","));
-
- //
- // Add the value of the UHD_IMAGES_DIR environment variable to the list of
- // directories searched for a LVBITX image.
- //
- char* uhd_images_dir;
-#ifdef UHD_PLATFORM_WIN32
- size_t len;
- errno_t err = _dupenv_s(&uhd_images_dir, &len, "UHD_IMAGES_DIR");
- if(not err and uhd_images_dir != NULL) search_path_vtr.push_back(std::string(uhd_images_dir));
- free(uhd_images_dir);
-#else
- uhd_images_dir = getenv("UHD_IMAGES_DIR");
- if(uhd_images_dir != NULL) search_path_vtr.push_back(std::string(uhd_images_dir));
-#endif
-
- std::string lvbitx_dir;
- //Traverse through the list of search paths. Priority: lexical
- BOOST_FOREACH(std::string& search_path, search_path_vtr) {
- boost::algorithm::trim(search_path);
- if (search_path.empty()) continue;
-
-#ifdef UHD_PLATFORM_WIN32
- lvbitx_dir = _get_path_from_registry(search_path);
- if (lvbitx_dir.empty()) {
- //Could not read from the registry due to missing key, invalid values, etc
- //Just use the search path. The is_directory check will fail if this is a
- //registry path and we will move on to the next item in the list.
- lvbitx_dir = search_path;
- }
-#else
- lvbitx_dir = search_path;
-#endif
-
- //If the current directory exists then stop traversing the search path list.
- if (boost::filesystem::is_directory(lvbitx_dir)) break;
- }
-
- return lvbitx_dir;
-}
-
-
}}
diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp
index 24a87a3c8..c4279913c 100644
--- a/host/lib/usrp/b100/b100_impl.cpp
+++ b/host/lib/usrp/b100/b100_impl.cpp
@@ -23,7 +23,7 @@
#include <uhd/utils/cast.hpp>
#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_call.hpp>
#include <boost/format.hpp>
#include <boost/assign/list_of.hpp>
@@ -82,7 +82,7 @@ static device_addrs_t b100_find(const device_addr_t &hint)
b100_fw_image = find_image_path(hint.get("fw", B100_FW_FILE_NAME));
}
catch(...){
- UHD_MSG(warning) << boost::format("Could not locate B100 firmware. %s\n") % print_images_error();
+ UHD_MSG(warning) << boost::format("Could not locate B100 firmware. %s\n") % print_utility_error("uhd_images_downloader.py");
return b100_addrs;
}
UHD_LOG << "the firmware image: " << b100_fw_image << std::endl;
@@ -532,10 +532,10 @@ void b100_impl::check_fw_compat(void){
);
if (fw_compat_num != B100_FW_COMPAT_NUM){
throw uhd::runtime_error(str(boost::format(
- "Expected firmware compatibility number 0x%x, but got 0x%x:\n"
+ "Expected firmware compatibility number %d, but got %d:\n"
"The firmware build is not compatible with the host code build.\n"
"%s"
- ) % B100_FW_COMPAT_NUM % fw_compat_num % print_images_error()));
+ ) % int(B100_FW_COMPAT_NUM) % fw_compat_num % print_utility_error("uhd_images_downloader.py")));
}
_tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num));
}
@@ -552,7 +552,7 @@ void b100_impl::check_fpga_compat(void){
"Expected FPGA compatibility number %d, but got %d:\n"
"The FPGA build is not compatible with the host code build."
"%s"
- ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_images_error()));
+ ) % int(B100_FPGA_COMPAT_NUM) % fpga_major % print_utility_error("uhd_images_downloader.py")));
}
_tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor));
}
diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp
index 59ea2202e..dbca543be 100644
--- a/host/lib/usrp/b100/b100_impl.hpp
+++ b/host/lib/usrp/b100/b100_impl.hpp
@@ -46,7 +46,7 @@
static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps)
static const std::string B100_FW_FILE_NAME = "usrp_b100_fw.ihx";
static const std::string B100_FPGA_FILE_NAME = "usrp_b100_fpga.bin";
-static const boost::uint16_t B100_FW_COMPAT_NUM = 0x04;
+static const boost::uint16_t B100_FW_COMPAT_NUM = 4;
static const boost::uint16_t B100_FPGA_COMPAT_NUM = 11;
static const boost::uint32_t B100_RX_SID_BASE = 30;
static const boost::uint32_t B100_TX_ASYNC_SID = 10;
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 13bdc09b4..355d12d12 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -17,12 +17,13 @@
#include "b200_impl.hpp"
#include "b200_regs.hpp"
+#include <uhd/config.hpp>
#include <uhd/transport/usb_control.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/cast.hpp>
#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
#include <boost/format.hpp>
@@ -109,13 +110,11 @@ static device_addrs_t b200_find(const device_addr_t &hint)
//extract the firmware path for the b200
std::string b200_fw_image;
try{
- b200_fw_image = find_image_path(hint.get("fw", B200_FW_FILE_NAME));
+ b200_fw_image = hint.get("fw", B200_FW_FILE_NAME);
+ b200_fw_image = uhd::find_image_path(b200_fw_image, STR(UHD_IMAGES_DIR)); // FIXME
}
- catch(...){
- UHD_MSG(warning) << boost::format(
- "Could not locate B200 firmware.\n"
- "Please install the images package. %s\n"
- ) % print_images_error();
+ catch(uhd::exception &e){
+ UHD_MSG(warning) << e.what();
return b200_addrs;
}
UHD_LOG << "the firmware image: " << b200_fw_image << std::endl;
@@ -783,11 +782,11 @@ void b200_impl::check_fw_compat(void)
if (compat_major != B200_FW_COMPAT_NUM_MAJOR){
throw uhd::runtime_error(str(boost::format(
- "Expected firmware compatibility number 0x%x, but got 0x%x.%x:\n"
+ "Expected firmware compatibility number %d.%d, but got %d.%d:\n"
"The firmware build is not compatible with the host code build.\n"
"%s"
- ) % int(B200_FW_COMPAT_NUM_MAJOR) % compat_major % compat_minor
- % print_images_error()));
+ ) % int(B200_FW_COMPAT_NUM_MAJOR) % int(B200_FW_COMPAT_NUM_MINOR)
+ % compat_major % compat_minor % print_utility_error("uhd_images_downloader.py")));
}
_tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.%u")
% compat_major % compat_minor));
@@ -804,11 +803,10 @@ void b200_impl::check_fpga_compat(void)
if (compat_major != B200_FPGA_COMPAT_NUM){
throw uhd::runtime_error(str(boost::format(
- "Expected FPGA compatibility number 0x%x, but got 0x%x.%x:\n"
+ "Expected FPGA compatibility number %d, but got %d:\n"
"The FPGA build is not compatible with the host code build.\n"
"%s"
- ) % int(B200_FPGA_COMPAT_NUM) % compat_major % compat_minor
- % print_images_error()));
+ ) % int(B200_FPGA_COMPAT_NUM) % compat_major % print_utility_error("uhd_images_downloader.py")));
}
_tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u")
% compat_major % compat_minor));
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index ab95ebce1..396819f9a 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -45,9 +45,9 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/weak_ptr.hpp>
#include "recv_packet_demuxer_3000.hpp"
-static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x07;
-static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0x00;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x04;
+static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 7;
+static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 4;
static const double B200_BUS_CLOCK_RATE = 100e6;
static const double B200_DEFAULT_TICK_RATE = 32e6;
static const double B200_DEFAULT_FREQ = 100e6; // Hz
diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp
index 8b4f2316c..ac419e0e0 100644
--- a/host/lib/usrp/e100/e100_impl.cpp
+++ b/host/lib/usrp/e100/e100_impl.cpp
@@ -21,7 +21,7 @@
#include <uhd/utils/msg.hpp>
#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <boost/bind.hpp>
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
@@ -132,7 +132,7 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){
e100_fpga_image = find_image_path(device_addr.get("fpga", default_fpga_file_name));
}
catch(...){
- UHD_MSG(error) << boost::format("Could not find FPGA image. %s\n") % print_images_error();
+ UHD_MSG(error) << boost::format("Could not find FPGA image. %s\n") % print_utility_error("uhd_images_downloader.py");
throw;
}
e100_load_fpga(e100_fpga_image);
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index 0c112fdb1..ac6294d5a 100644
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ b/host/lib/usrp/e300/e300_impl.cpp
@@ -28,7 +28,7 @@
#include <uhd/utils/msg.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/transport/if_addrs.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
@@ -397,7 +397,7 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
"%s"
) % fpga::COMPAT_MAJOR
% _get_version(FPGA_MAJOR) % _get_version(FPGA_MINOR)
- % print_images_error()));
+ % print_utility_error("uhd_images_downloader.py")));
}
////////////////////////////////////////////////////////////////////
diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp
index 2c37f2ff1..bb904773b 100644
--- a/host/lib/usrp/e300/e300_network.cpp
+++ b/host/lib/usrp/e300/e300_network.cpp
@@ -33,7 +33,7 @@
#include <uhd/utils/msg.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 709092e42..dbd5408e8 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -23,7 +23,7 @@
#include <uhd/utils/cast.hpp>
#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <boost/format.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/filesystem.hpp>
@@ -85,7 +85,7 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
usrp1_fw_image = find_image_path(hint.get("fw", "usrp1_fw.ihx"));
}
catch(...){
- UHD_MSG(warning) << boost::format("Could not locate USRP1 firmware. %s") % print_images_error();
+ UHD_MSG(warning) << boost::format("Could not locate USRP1 firmware. %s") % print_utility_error("uhd_images_downloader.py");
}
UHD_LOG << "USRP1 firmware image: " << usrp1_fw_image << std::endl;
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index b2085807f..65cf90a17 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -23,7 +23,7 @@
#include <uhd/utils/msg.hpp>
#include <uhd/utils/paths.hpp>
#include <uhd/utils/tasks.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhd/types/dict.hpp>
#include <boost/thread.hpp>
@@ -375,7 +375,7 @@ public:
fpga_image_path = uhd::find_image_path(fpga_image);
}
catch(const std::exception &){
- return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_images_error());
+ return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_utility_error("uhd_images_downloader.py"));
}
//escape char for multi-line cmd + newline + indent?
@@ -389,13 +389,13 @@ public:
if (this->get_rev() == USRP2_REV3 or this->get_rev() == USRP2_REV4){
const std::string card_burner = (fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "usrp2_card_burner.py").string();
const std::string card_burner_cmd = str(boost::format("\"%s%s\" %s--fpga=\"%s\" %s--fw=\"%s\"") % sudo % card_burner % ml % fpga_image_path % ml % fw_image_path);
- return str(boost::format("%s\n%s") % print_images_error() % card_burner_cmd);
+ return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % card_burner_cmd);
}
else{
const std::string addr = _ctrl_transport->get_recv_addr();
const std::string net_burner_path = (fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "usrp_n2xx_simple_net_burner").string();
const std::string net_burner_cmd = str(boost::format("\"%s\" %s--addr=\"%s\"") % net_burner_path % ml % addr);
- return str(boost::format("%s\n%s") % print_images_error() % net_burner_cmd);
+ return str(boost::format("%s\n%s") % print_utility_error("uhd_images_downloader.py") % net_burner_cmd);
}
}
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index eab5cfef2..e35f73eab 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -24,7 +24,7 @@
#include "apply_corrections.hpp"
#include <uhd/utils/static.hpp>
#include <uhd/utils/msg.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/transport/if_addrs.hpp>
@@ -171,7 +171,7 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
default:
continue;
}
-
+
niriok_proxy::sptr kernel_proxy = niriok_proxy::make_and_open(dev_info.interface_path);
//Attempt to read the name from the EEPROM and perform filtering.
@@ -1668,11 +1668,11 @@ void x300_impl::check_fw_compat(const fs_path &mb_path, wb_iface::sptr iface)
if (compat_major != X300_FW_COMPAT_MAJOR)
{
throw uhd::runtime_error(str(boost::format(
- "Expected firmware compatibility number 0x%x, but got 0x%x.%x:\n"
+ "Expected firmware compatibility number %d.%d, but got %d.%d:\n"
"The firmware build is not compatible with the host code build.\n"
"%s"
- ) % int(X300_FW_COMPAT_MAJOR) % compat_major % compat_minor
- % print_images_error()));
+ ) % int(X300_FW_COMPAT_MAJOR) % int(X300_FW_COMPAT_MINOR)
+ % compat_major % compat_minor % print_utility_error("uhd_images_downloader.py")));
}
_tree->create<std::string>(mb_path / "fw_version").set(str(boost::format("%u.%u")
% compat_major % compat_minor));
@@ -1692,11 +1692,11 @@ void x300_impl::check_fpga_compat(const fs_path &mb_path, wb_iface::sptr iface)
"Download the appropriate FPGA images for this version of UHD.\n"
"%s\n\n"
"Then burn a new image to the on-board flash storage of your\n"
- "USRP X3xx device using the burner utility. \n\n"
+ "USRP X3xx device using the burner utility. %s\n\n"
"For more information, refer to the UHD manual:\n\n"
" http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash"
) % int(X300_FPGA_COMPAT_MAJOR) % compat_major
- % print_images_error()));
+ % print_utility_error("uhd_images_downloader.py") % print_utility_error("usrp_x3xx_fpga_burner")));
}
_tree->create<std::string>(mb_path / "fpga_version").set(str(boost::format("%u.%u")
% compat_major % compat_minor));
diff --git a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp
index 8c207dd9f..d55fab10e 100644
--- a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp
+++ b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp
@@ -33,7 +33,7 @@
#include <uhd/usrp/gps_ctrl.hpp>
#include <uhd/usrp_clock/octoclock_eeprom.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/paths.hpp>
#include <uhd/utils/static.hpp>
@@ -420,7 +420,7 @@ std::string octoclock_impl::_get_images_help_message(const std::string &addr){
catch(const std::exception &e){
return str(boost::format("Could not find %s in your images path.\n%s")
% image_name
- % uhd::print_images_error());
+ % uhd::print_utility_error("uhd_images_downloader.py"));
}
//Get escape character
@@ -433,5 +433,5 @@ std::string octoclock_impl::_get_images_help_message(const std::string &addr){
//Get burner command
const std::string burner_path = (fs::path(uhd::get_pkg_path()) / "bin" / "octoclock_firmware_burner").string();
const std::string burner_cmd = str(boost::format("%s %s--addr=\"%s\"") % burner_path % ml % addr);
- return str(boost::format("%s\n%s") % uhd::print_images_error() % burner_cmd);
+ return str(boost::format("%s\n%s") % uhd::print_utility_error("uhd_images_downloader.py") % burner_cmd);
}
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
index 106e2b650..369920ac1 100644
--- a/host/lib/utils/CMakeLists.txt
+++ b/host/lib/utils/CMakeLists.txt
@@ -132,7 +132,6 @@ SET_SOURCE_FILES_PROPERTIES(
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/csv.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/images.cpp
${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp
${CMAKE_CURRENT_SOURCE_DIR}/log.cpp
${CMAKE_CURRENT_SOURCE_DIR}/msg.cpp
diff --git a/host/lib/utils/images.cpp b/host/lib/utils/images.cpp
deleted file mode 100644
index 1ba2f81e6..000000000
--- a/host/lib/utils/images.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright 2010-2012 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/utils/images.hpp>
-#include <uhd/exception.hpp>
-#include <uhd/utils/paths.hpp>
-#include <boost/foreach.hpp>
-#include <boost/filesystem.hpp>
-#include <vector>
-#include <iostream>
-
-namespace fs = boost::filesystem;
-
-std::vector<fs::path> get_image_paths(void); //defined in paths.cpp
-
-/***********************************************************************
- * Find an image in the image paths
- **********************************************************************/
-std::string uhd::find_image_path(const std::string &image_name){
- if (fs::exists(image_name)){
- return fs::system_complete(image_name).string();
- }
- BOOST_FOREACH(const fs::path &path, get_image_paths()){
- fs::path image_path = path / image_name;
- if (fs::exists(image_path)) return image_path.string();
- }
- throw uhd::io_error("Could not find path for image: " + image_name + "\n\n" + uhd::print_images_error());
-}
-
-std::string uhd::find_images_downloader(void){
- return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "uhd_images_downloader.py").string();
-}
-
-std::string uhd::print_images_error(void){
- #ifdef UHD_PLATFORM_WIN32
- return "As an Administrator, please run:\n\n\"" + find_images_downloader() + "\"";
- #else
- return "Please run:\n\nsudo \"" + find_images_downloader() + "\"";
- #endif
-}
diff --git a/host/lib/utils/load_modules.cpp b/host/lib/utils/load_modules.cpp
index bee0d5304..aba3adeed 100644
--- a/host/lib/utils/load_modules.cpp
+++ b/host/lib/utils/load_modules.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/exception.hpp>
#include <boost/format.hpp>
@@ -97,13 +98,11 @@ static void load_module_path(const fs::path &path){
}
}
-std::vector<fs::path> get_module_paths(void); //defined in paths.cpp
-
/*!
* Load all the modules given in the module paths.
*/
UHD_STATIC_BLOCK(load_modules){
- BOOST_FOREACH(const fs::path &path, get_module_paths()){
+ BOOST_FOREACH(const fs::path &path, uhd::get_module_paths()){
load_module_path(path);
}
}
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
index 3e2bea1c6..e304555bd 100644
--- a/host/lib/utils/paths.cpp
+++ b/host/lib/utils/paths.cpp
@@ -16,37 +16,77 @@
//
#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/transport/nirio/nifpga_lvbitx.h>
#include <uhd/utils/paths.hpp>
-#include <boost/tokenizer.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
-#include <boost/bind.hpp>
+#include <boost/format.hpp>
+#include <boost/regex.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <cstdio>
#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <streambuf>
#include <string>
#include <vector>
-#include <cstdlib> //getenv
-#include <cstdio> //P_tmpdir
+
#ifdef BOOST_MSVC
#define USE_GET_TEMP_PATH
#include <windows.h> //GetTempPath
#endif
+#ifdef USE_NIUSRP_WINREG_KEY
+#define NIUSRP_WINREG_KEY "[HKLM\\Software\\National Instruments\\NI-USRP\\DriverBitfilesDir]"
+#endif
+
namespace fs = boost::filesystem;
-/***********************************************************************
- * Get a list of paths for an environment variable
- **********************************************************************/
-static std::string get_env_var(const std::string &var_name, const std::string &def_val = ""){
- const char *var_value_ptr = std::getenv(var_name.c_str());
- return (var_value_ptr == NULL)? def_val : var_value_ptr;
-}
+/*! Get the value of an environment variable.
+ *
+ * The returned std::string is the full environment variable string, and thus
+ * may actually contain multiple fields in the string with delimiters.
+ *
+ * \param var_name The name of the variable to search for.
+ * \param default_val A default string value to use if the path isn't found.
+ * \returns The string value of the environment variable.
+ */
+static std::string get_env_var(const std::string &var_name,
+ const std::string &default_val = "") {
-static std::vector<fs::path> get_env_paths(const std::string &var_name){
+ std::string env_result = default_val;
+ char *env_var_str = NULL;
-/***********************************************************************
- * Determine the paths separator
- **********************************************************************/
+ /* Some versions of MinGW don't expose `_dupenv_s` */
+#if defined(UHD_PLATFORM_WIN32) && !defined(__MINGW32__)
+ size_t len;
+ errno_t err = _dupenv_s(&env_var_str, &len, var_name.c_str());
+ if((not err) and (env_var_str != NULL))
+ env_result = std::string(env_var_str);
+ free(env_var_str);
+#else
+ env_var_str = std::getenv(var_name.c_str());
+ if(env_var_str != NULL)
+ env_result = std::string(env_var_str);
+#endif
+ return env_result;
+}
+
+/*! Get a vector of paths from an environment variable.
+ *
+ * Reads an environment variable, which should contain a list of paths, and
+ * returns a vector of those paths in the form of strings.
+ *
+ * \param var_name The environment variable name to read.
+ * \returns The vector of paths from the environment variable.
+ */
+static std::vector<std::string> get_env_paths(const std::string &var_name){
#ifdef UHD_PLATFORM_WIN32
static const std::string env_path_sep = ";";
#else
@@ -59,40 +99,45 @@ static std::vector<fs::path> get_env_paths(const std::string &var_name){
std::string var_value = get_env_var(var_name);
- //convert to filesystem path, filter blank paths
- std::vector<fs::path> paths;
- if (var_value.empty()) return paths; //FIXME boost tokenizer throws w/ blank strings on some platforms
+ std::vector<std::string> paths;
+
+ //convert to full filesystem path, filter blank paths
+ if (var_value.empty()) return paths;
BOOST_FOREACH(const std::string &path_string, path_tokenizer(var_value)){
if (path_string.empty()) continue;
- paths.push_back(fs::system_complete(path_string));
+ paths.push_back(fs::system_complete(path_string).string());
}
+
return paths;
}
-/***********************************************************************
- * Get a list of special purpose paths
- **********************************************************************/
-std::string uhd::get_pkg_path(void)
-{
- return get_env_var("UHD_PKG_PATH", UHD_PKG_PATH);
-}
+/*! Expand a tilde character to the $HOME path.
+ *
+ * The path passed to this function must start with the tilde character in order
+ * for this function to work properly. If it does not, it will simply return the
+ * original path. The $HOME environment variable must exist.
+ *
+ * \param path The path starting with the tilde character
+ * \returns The same path with the tilde expanded to contents of $HOME.
+ */
+static std::string expand_home_directory(std::string path) {
+ boost::trim(path);
-std::vector<fs::path> get_image_paths(void){
- std::vector<fs::path> paths = get_env_paths("UHD_IMAGE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "images");
- return paths;
-}
+ if(path.empty() || (path[0] != '~')) {
+ return path;
+ }
-std::vector<fs::path> get_module_paths(void){
- std::vector<fs::path> paths = get_env_paths("UHD_MODULE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "modules");
- paths.push_back(fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "modules");
- return paths;
+ std::string user_home_path = get_env_var("HOME");
+ path.replace(0, 1, user_home_path);
+
+ return path;
}
/***********************************************************************
* Implement the functions in paths.hpp
**********************************************************************/
+
+
std::string uhd::get_tmp_path(void){
const char *tmp_path = NULL;
@@ -136,3 +181,192 @@ std::string uhd::get_app_path(void){
return uhd::get_tmp_path();
}
+
+std::string uhd::get_pkg_path(void) {
+ return get_env_var("UHD_PKG_PATH", UHD_PKG_PATH);
+}
+
+std::vector<fs::path> uhd::get_module_paths(void){
+ std::vector<fs::path> paths;
+
+ std::vector<std::string> env_paths = get_env_paths("UHD_MODULE_PATH");
+ BOOST_FOREACH(std::string &str_path, env_paths) {
+ paths.push_back(str_path);
+ }
+
+ paths.push_back(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "modules");
+ paths.push_back(fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "modules");
+
+ return paths;
+}
+
+#ifdef UHD_PLATFORM_WIN32
+#include <windows.h>
+/*!
+ * On Windows, query the system registry for the UHD images install path.
+ * If the key isn't found in the registry, an empty string is returned.
+ * \param registry_key_path The registry key to look for.
+ * \return The images path, formatted for windows.
+ */
+std::string _get_images_path_from_registry(const std::string& registry_key_path) {
+ boost::smatch reg_key_match;
+ //If a substring in the search path is enclosed in [] (square brackets) then it is interpreted as a registry path
+ if (not boost::regex_search(registry_key_path, reg_key_match, boost::regex("\\[(.+)\\](.*)", boost::regex::icase)))
+ return std::string();
+ std::string reg_key_path = std::string(reg_key_match[1].first, reg_key_match[1].second);
+ std::string path_suffix = std::string(reg_key_match[2].first, reg_key_match[2].second);
+
+ //Split the registry path into parent, key-path and value.
+ boost::smatch reg_parent_match;
+ if (not boost::regex_search(reg_key_path, reg_parent_match, boost::regex("^(.+?)\\\\(.+)\\\\(.+)$", boost::regex::icase)))
+ return std::string();
+ std::string reg_parent = std::string(reg_parent_match[1].first, reg_parent_match[1].second);
+ std::string reg_path = std::string(reg_parent_match[2].first, reg_parent_match[2].second);
+ std::string reg_val_name = std::string(reg_parent_match[3].first, reg_parent_match[3].second);
+
+ HKEY hkey_parent = HKEY_LOCAL_MACHINE;
+ if (reg_parent == "HKEY_LOCAL_MACHINE") hkey_parent = HKEY_LOCAL_MACHINE;
+ else if (reg_parent == "HKEY_CURRENT_USER") hkey_parent = HKEY_CURRENT_USER;
+ else if (reg_parent == "HKEY_CLASSES_ROOT") hkey_parent = HKEY_CLASSES_ROOT;
+ else if (reg_parent == "HKEY_CURRENT_CONFIG") hkey_parent = HKEY_CURRENT_CONFIG;
+ else if (reg_parent == "HKEY_USERS") hkey_parent = HKEY_CURRENT_USER;
+
+ TCHAR value_buff[1024];
+ DWORD value_buff_size = 1024*sizeof(TCHAR);
+
+ //Get a handle to the key location
+ HKEY hkey_location;
+ if (RegOpenKeyExA(hkey_parent, reg_path.c_str(), NULL, KEY_QUERY_VALUE, &hkey_location) != ERROR_SUCCESS)
+ return std::string();
+
+ //Query key value
+ DWORD dw_type = REG_SZ;
+ if(RegQueryValueExA(hkey_location, reg_val_name.c_str(), NULL, &dw_type, (LPBYTE)value_buff, &value_buff_size) == ERROR_SUCCESS) {
+ RegCloseKey(hkey_location);
+ if (value_buff_size >= 1024*sizeof(TCHAR)) {
+ return std::string();
+ } else {
+ std::string return_value(value_buff, value_buff_size-1); //value_buff_size includes the null terminator
+ return_value += path_suffix;
+ return return_value;
+ }
+ } else {
+ return std::string();
+ }
+}
+#endif /*UHD_PLATFORM_WIN32*/
+
+std::string uhd::get_images_dir(const std::string search_paths) {
+
+ /* This function will check for the existence of directories in this
+ * order:
+ *
+ * 1) `UHD_IMAGES_DIR` environment variable
+ * 2) Any paths passed to this function via `search_paths' (may contain
+ * Windows registry keys)
+ * 3) `UHD package path` / share / uhd / images
+ */
+
+ std::string possible_dir;
+
+ /* We will start by looking for a path indicated by the `UHD_IMAGES_DIR`
+ * environment variable. */
+ std::vector<std::string> env_paths = get_env_paths("UHD_IMAGES_DIR");
+ BOOST_FOREACH(possible_dir, env_paths) {
+ if (fs::is_directory(fs::path(possible_dir))) {
+ return possible_dir;
+ }
+ }
+
+ /* On Windows systems, we may need to modify the `search_paths` parameter
+ * (see below). Making a local copy for const correctness. */
+ std::string _search_paths = search_paths;
+
+#ifdef USE_NIUSRP_WINREG_KEY
+ _search_paths = std::string(NIUSRP_WINREG_KEY) + "," + search_paths;
+#endif
+
+ /* Now we will parse and attempt to qualify the paths in the `search_paths`
+ * parameter. If this is Windows, we will check the system registry for
+ * these strings. */
+ if (!_search_paths.empty()) {
+ std::vector<std::string> search_paths_vector;
+
+ boost::split(search_paths_vector, _search_paths, boost::is_any_of(",;"));
+ BOOST_FOREACH(std::string& search_path, search_paths_vector) {
+
+ boost::algorithm::trim(search_path);
+ if (search_path.empty()) continue;
+
+#ifdef UHD_PLATFORM_WIN32
+ possible_dir = _get_images_path_from_registry(search_path);
+ if (possible_dir.empty()) {
+ //Could not read from the registry due to missing key, invalid
+ //values, etc Just use the search path. The is_directory check
+ //will fail if this is a registry path and we will move on to
+ //the next item in the list.
+ possible_dir = search_path;
+ }
+#else
+ possible_dir = expand_home_directory(search_path);
+#endif
+
+ if (fs::is_directory(fs::path(possible_dir))) {
+ return possible_dir;
+ }
+ }
+ }
+
+ /* Finally, check for the default UHD images installation path. */
+ fs::path pkg_path = fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "images";
+ if (fs::is_directory(pkg_path)) {
+ return pkg_path.string();
+ } else {
+ /* No luck. Return an empty string. */
+ return std::string("");
+ }
+}
+
+std::string uhd::find_image_path(const std::string &image_name, const std::string search_paths){
+ /* If a path was provided on the command-line or as a hint from the caller,
+ * we default to that. */
+ if (fs::exists(image_name)){
+ return fs::system_complete(image_name).string();
+ }
+
+ /* Otherwise, look for the image in the images directory. */
+ std::string images_dir = get_images_dir(search_paths);
+ if (!images_dir.empty()) {
+ fs::path image_path = fs::path(images_dir) / image_name;
+ if (fs::exists(image_path)) {
+ return image_path.string();
+ } else {
+ throw uhd::io_error(
+ "Could not find the image '" + image_name + "' in the image directory " + images_dir
+ + "\nFor more information regarding image paths, please refer to the UHD manual.");
+ }
+ }
+
+ /* If we made it this far, then we didn't find anything. */
+ throw uhd::io_error("Could not find path for image: " + image_name
+ + "\n\n"
+ + "Using images directory: " + images_dir
+ + "\n\n"
+ + "Set the environment variable 'UHD_IMAGES_DIR' appropriately or"
+ + " follow the below instructions to download the images package."
+ + "\n\n"
+ + uhd::print_utility_error("uhd_images_downloader.py"));
+}
+
+std::string uhd::find_utility(std::string name) {
+ return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / name)
+ .string();
+}
+
+std::string uhd::print_utility_error(std::string name){
+ #ifdef UHD_PLATFORM_WIN32
+ return "As an Administrator, please run:\n\n\"" + find_utility(name) + "\"";
+ #else
+ return "Please run:\n\n \"" + find_utility(name) + "\"";
+ #endif
+}
diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp
index 0cab6618d..8b64be63e 100644
--- a/host/utils/b2xx_fx3_utils.cpp
+++ b/host/utils/b2xx_fx3_utils.cpp
@@ -39,7 +39,7 @@
#include <uhd/transport/usb_control.hpp>
#include <uhd/transport/usb_device_handle.hpp>
#include <uhd/exception.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;
diff --git a/host/utils/octoclock_firmware_burner.cpp b/host/utils/octoclock_firmware_burner.cpp
index 9551ddd20..0a48caabd 100644
--- a/host/utils/octoclock_firmware_burner.cpp
+++ b/host/utils/octoclock_firmware_burner.cpp
@@ -37,7 +37,7 @@
#include <uhd/types/device_addr.hpp>
#include <uhd/types/time_spec.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_main.hpp>
diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp
index dc83b6fdf..b06e67bb2 100644
--- a/host/utils/usrp_n2xx_simple_net_burner.cpp
+++ b/host/utils/usrp_n2xx_simple_net_burner.cpp
@@ -38,7 +38,7 @@
#include <uhd/transport/udp_simple.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/safe_call.hpp>
diff --git a/host/utils/usrp_x3xx_fpga_burner.cpp b/host/utils/usrp_x3xx_fpga_burner.cpp
index b849cfb92..abd5815e8 100644
--- a/host/utils/usrp_x3xx_fpga_burner.cpp
+++ b/host/utils/usrp_x3xx_fpga_burner.cpp
@@ -45,7 +45,7 @@
#include <uhd/device.hpp>
#include <uhd/types/device_addr.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/images.hpp>
+#include <uhd/utils/paths.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/safe_call.hpp>