diff options
| author | Martin Braun <martin.braun@ettus.com> | 2018-01-31 20:20:14 +0100 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2018-03-14 15:17:44 -0700 | 
| commit | 6652eb4a033b38bd952563f3544eb11e98f27327 (patch) | |
| tree | c1b0af72cbaceaa1df462f18194f4063fb13ae17 /host/lib/include/uhdlib/utils | |
| parent | 86b95486ed6d68e2772d79f20feddbef5439981b (diff) | |
| download | uhd-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.hpp | 20 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/utils/ihex.hpp | 69 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/utils/rpc.hpp | 191 | 
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 */  | 
