aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib/utils
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2018-01-31 20:20:14 +0100
committerMartin Braun <martin.braun@ettus.com>2018-03-14 15:17:44 -0700
commit6652eb4a033b38bd952563f3544eb11e98f27327 (patch)
treec1b0af72cbaceaa1df462f18194f4063fb13ae17 /host/lib/include/uhdlib/utils
parent86b95486ed6d68e2772d79f20feddbef5439981b (diff)
downloaduhd-6652eb4a033b38bd952563f3544eb11e98f27327.tar.gz
uhd-6652eb4a033b38bd952563f3544eb11e98f27327.tar.bz2
uhd-6652eb4a033b38bd952563f3544eb11e98f27327.zip
uhd: Move internal headers to uhdlib/
To avoid the proliferation of additional include directories and multiple ways of including project-local headers, we now default to moving all headers that are used across UHD into the uhdlib/ subdirectory. Some #include statements were also reordered as they were modified for closer compliance with the coding guidelines. Internal cpp source files should now include files like this: #include <uhdlib/rfnoc/ctrl_iface.hpp> Reviewed-by: Ashish Chaudhari <ashish.chaudhari@ettus.com>
Diffstat (limited to 'host/lib/include/uhdlib/utils')
-rw-r--r--host/lib/include/uhdlib/utils/eeprom_utils.hpp20
-rw-r--r--host/lib/include/uhdlib/utils/ihex.hpp69
-rw-r--r--host/lib/include/uhdlib/utils/rpc.hpp191
3 files changed, 280 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/utils/eeprom_utils.hpp b/host/lib/include/uhdlib/utils/eeprom_utils.hpp
new file mode 100644
index 000000000..28deca790
--- /dev/null
+++ b/host/lib/include/uhdlib/utils/eeprom_utils.hpp
@@ -0,0 +1,20 @@
+//
+// Copyright 2017 Ettus Research (National Instruments Corp.)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/types/byte_vector.hpp>
+#include <uhd/types/mac_addr.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <string>
+#include <vector>
+
+static const size_t SERIAL_LEN = 9;
+static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN;
+
+//! convert a string to a byte vector to write to eeprom
+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);
diff --git a/host/lib/include/uhdlib/utils/ihex.hpp b/host/lib/include/uhdlib/utils/ihex.hpp
new file mode 100644
index 000000000..4b1be77f1
--- /dev/null
+++ b/host/lib/include/uhdlib/utils/ihex.hpp
@@ -0,0 +1,69 @@
+//
+// Copyright 2015 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_IHEX_READER_HPP
+#define INCLUDED_IHEX_READER_HPP
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace uhd {
+
+class ihex_reader
+{
+public:
+ // Arguments are: lower address bits, upper address bits, buff, length
+ typedef boost::function<int(uint16_t,uint16_t,unsigned char*,uint16_t)> record_handle_type;
+
+ /*
+ * \param ihex_filename Path to the *.ihx file
+ */
+ ihex_reader(const std::string &ihex_filename);
+
+ /*! Read an Intel HEX file and handle it record by record.
+ *
+ * Every record is individually passed off to a record handler function.
+ *
+ * \param record_handler The functor that will handle the records.
+ *
+ * \throws uhd::io_error if the HEX file is corrupted or unreadable.
+ */
+ void read(record_handle_type record_handler);
+
+ /* Convert the ihex file to a bin file.
+ *
+ * *Note:* This function makes the assumption that the hex file is
+ * contiguous, and starts at address zero.
+ *
+ * \param bin_filename Output filename.
+ *
+ * \throws uhd::io_error if the HEX file is corrupted or unreadable.
+ */
+ void to_bin_file(const std::string &bin_filename);
+
+ /*! Copy the ihex file into a buffer.
+ *
+ * Very similar functionality as to_bin_file().
+ *
+ * *Note:* This function makes the assumption that the hex file is
+ * contiguous, and starts at address zero.
+ *
+ * \throws uhd::io_error if the HEX file is corrupted or unreadable.
+ */
+ std::vector<uint8_t> to_vector(const size_t size_estimate = 0);
+
+private:
+ const std::string _ihex_filename;
+};
+
+}; /* namespace uhd */
+
+#endif /* INCLUDED_IHEX_READER_HPP */
+
diff --git a/host/lib/include/uhdlib/utils/rpc.hpp b/host/lib/include/uhdlib/utils/rpc.hpp
new file mode 100644
index 000000000..c7c27afd2
--- /dev/null
+++ b/host/lib/include/uhdlib/utils/rpc.hpp
@@ -0,0 +1,191 @@
+//
+// Copyright 2017 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_UTILS_RPC_HPP
+#define INCLUDED_UTILS_RPC_HPP
+
+#include <rpc/client.h>
+#include <rpc/rpc_error.h>
+#include <uhd/utils/log.hpp>
+#include <uhd/exception.hpp>
+#include <boost/format.hpp>
+
+namespace uhd {
+
+/*! Abstraction for RPC client
+ *
+ * Purpose of this class is to wrap the underlying RPC implementation.
+ * This class holds a connection to an RPC server (the connection is severed on
+ * destruction).
+ */
+class rpc_client
+{
+ public:
+ using sptr = std::shared_ptr<rpc_client>;
+
+ static sptr make(
+ const std::string &addr,
+ const uint16_t port,
+ const std::string &get_last_error_cmd=""
+ ) {
+ return std::make_shared<rpc_client>(addr, port, get_last_error_cmd);
+ }
+
+ /*!
+ * \param addr An IP address to connect to
+ * \param port Port to connect to
+ * \param get_last_error_cmd A command that queries an error string from
+ * the RPC server. If set, the RPC client will
+ * try and use this command to fetch information
+ * about what went wrong on the client side.
+ */
+ rpc_client(
+ const std::string &addr,
+ const uint16_t port,
+ std::string const &get_last_error_cmd=""
+ ) : _client(addr, port)
+ , _get_last_error_cmd(get_last_error_cmd)
+ {
+ // nop
+ }
+
+ /*! Perform an RPC request.
+ *
+ * Thread safe (locked). This function blocks until it receives a valid
+ * response from the server.
+ *
+ * \param func_name The function name that is called via RPC
+ * \param args All these arguments are passed to the RPC call
+ *
+ * \throws uhd::runtime_error in case of failure
+ */
+ template <typename return_type, typename... Args>
+ return_type request(std::string const& func_name, Args&&... args)
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ try {
+ return _client.call(func_name, std::forward<Args>(args)...)
+ .template as<return_type>();
+ } catch (const ::rpc::rpc_error &ex) {
+ const std::string error = _get_last_error_safe();
+ if (not error.empty()) {
+ UHD_LOG_ERROR("RPC", error);
+ }
+ throw uhd::runtime_error(str(
+ boost::format("Error during RPC call to `%s'. Error message: %s")
+ % func_name % (error.empty() ? ex.what() : error)
+ ));
+ } catch (const std::bad_cast& ex) {
+ throw uhd::runtime_error(str(
+ boost::format("Error during RPC call to `%s'. Error message: %s")
+ % func_name % ex.what()
+ ));
+ }
+ };
+
+ /*! Perform an RPC notification.
+ *
+ * Thread safe (locked). This function does not require a response from the
+ * server, although the underlying implementation may provide one.
+ *
+ * \param func_name The function name that is called via RPC
+ * \param args All these arguments are passed to the RPC call
+ *
+ * \throws uhd::runtime_error in case of failure
+ */
+ template <typename... Args>
+ void notify(std::string const& func_name, Args&&... args)
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ try {
+ _client.call(func_name, std::forward<Args>(args)...);
+ } catch (const ::rpc::rpc_error &ex) {
+ const std::string error = _get_last_error_safe();
+ if (not error.empty()) {
+ UHD_LOG_ERROR("RPC", error);
+ }
+ throw uhd::runtime_error(str(
+ boost::format("Error during RPC call to `%s'. Error message: %s")
+ % func_name % (error.empty() ? ex.what() : error)
+ ));
+ } catch (const std::bad_cast& ex) {
+ throw uhd::runtime_error(str(
+ boost::format("Error during RPC call to `%s'. Error message: %s")
+ % func_name % ex.what()
+ ));
+ }
+ };
+
+ /*! Like request(), also provides a token.
+ *
+ * This is a convenience wrapper to directly call a function that requires
+ * a token without having to have a copy of the token.
+ */
+ template <typename return_type, typename... Args>
+ return_type request_with_token(std::string const& func_name, Args&&... args)
+ {
+ return request<return_type>(func_name, _token, std::forward<Args>(args)...);
+ };
+
+ /*! Like notify(), also provides a token.
+ *
+ * This is a convenience wrapper to directly call a function that requires
+ * a token without having to have a copy of the token.
+ */
+ template <typename... Args>
+ void notify_with_token(std::string const& func_name, Args&&... args)
+ {
+ notify(func_name, _token, std::forward<Args>(args)...);
+ };
+
+ /*! Sets the token value. This is used by the `_with_token` methods.
+ */
+ void set_token(const std::string &token)
+ {
+ _token = token;
+ }
+
+ void set_timeout(size_t timeout_ms)
+ {
+ _client.set_timeout(timeout_ms);
+ }
+
+ private:
+ /*! Pull the last error out of the RPC server. Not thread-safe, meant to
+ * be called from notify() or request().
+ *
+ * This function will do its best not to get in anyone's way. If it can't
+ * get an error string, it'll return an empty string.
+ */
+ std::string _get_last_error_safe()
+ {
+ if (_get_last_error_cmd.empty()) {
+ return "";
+ }
+ try {
+ return _client.call(_get_last_error_cmd).as<std::string>();
+ } catch (const ::rpc::rpc_error &ex) {
+ // nop
+ } catch (const std::bad_cast& ex) {
+ // nop
+ } catch (...) {
+ // nop
+ }
+ return "";
+ }
+
+ //! Reference the actual RPC client
+ ::rpc::client _client;
+ //! If set, this is the command that will retrieve an error
+ const std::string _get_last_error_cmd;
+
+ std::string _token;
+ std::mutex _mutex;
+};
+
+} /* namespace uhd */
+
+#endif /* INCLUDED_UTILS_RPC_HPP */