diff options
-rw-r--r-- | .gitignore | 20 | ||||
-rw-r--r-- | AUTHORS | 0 | ||||
-rw-r--r-- | COPYING | 0 | ||||
-rw-r--r-- | ChangeLog | 0 | ||||
-rw-r--r-- | INSTALL | 0 | ||||
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | Makefile.common | 9 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rw-r--r-- | README | 0 | ||||
-rw-r--r-- | config/ax_boost_base.m4 | 237 | ||||
-rw-r--r-- | config/ax_boost_thread.m4 | 144 | ||||
-rw-r--r-- | configure.ac | 36 | ||||
-rw-r--r-- | usrp_uhd/.gitignore | 3 | ||||
-rw-r--r-- | usrp_uhd/Makefile.am | 13 | ||||
-rw-r--r-- | usrp_uhd/include/.gitignore | 2 | ||||
-rw-r--r-- | usrp_uhd/include/Makefile.am | 14 | ||||
-rw-r--r-- | usrp_uhd/include/usrp_uhd.hpp | 43 | ||||
-rw-r--r-- | usrp_uhd/include/usrp_uhd/usrp_addr.hpp | 90 | ||||
-rw-r--r-- | usrp_uhd/include/usrp_uhd/wax.hpp | 129 | ||||
-rw-r--r-- | usrp_uhd/lib/.gitignore | 2 | ||||
-rw-r--r-- | usrp_uhd/lib/Makefile.am | 25 | ||||
-rw-r--r-- | usrp_uhd/lib/usrp_addr.cpp | 116 | ||||
-rw-r--r-- | usrp_uhd/lib/usrp_uhd.cpp | 10 | ||||
-rw-r--r-- | usrp_uhd/lib/wax.cpp | 71 | ||||
-rw-r--r-- | usrp_uhd/usrp_uhd.pc.in | 11 |
25 files changed, 982 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..cce871cf4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +/Makefile +/Makefile.in +/aclocal.m4 +/autom4te.cache/ +/bootstrap +/config.guess +/config.log +/config.status +/config.sub +/configure +/install-sh +/libtool +/ltmain.sh +/missing +/depcomp +*.la +*.lo +*.o +*.libs +*.deps diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/AUTHORS diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/COPYING diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ChangeLog diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/INSTALL diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..9658b5bd8 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +# +# Copyright 2010 Ettus Research LLC +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = usrp_uhd diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 000000000..9b81eb842 --- /dev/null +++ b/Makefile.common @@ -0,0 +1,9 @@ +# +# Copyright 2010 Ettus Research LLC +# + +USRP_UHD_INCLUDES = \ + -I$(top_srcdir)/usrp_uhd/include + +USRP_UHD_LA = \ + $(top_srcdir)/usrp_uhd/lib/libusrp_uhd.la diff --git a/config/ax_boost_base.m4 b/config/ax_boost_base.m4 new file mode 100644 index 000000000..3940abaea --- /dev/null +++ b/config/ax_boost_base.m4 @@ -0,0 +1,237 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_boost_base.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Test for the Boost C++ libraries of a particular version (or newer) +# +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt and /opt/local and evaluates the +# $BOOST_ROOT environment variable. Further documentation is available at +# <http://randspringer.de/boost/index.html>. +# +# This macro calls: +# +# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) +# +# And sets: +# +# HAVE_BOOST +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2009 Peter Adolphs +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +AC_DEFUN([AX_BOOST_BASE], +[ +AC_ARG_WITH([boost], + [AC_HELP_STRING([--with-boost@<:@=ARG@:>@], + [use Boost library from a standard location (ARG=yes), + from the specified location (ARG=<path>), + or disable it (ARG=no) + @<:@ARG=yes@:>@ ])], + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ac_boost_path="" + else + want_boost="yes" + ac_boost_path="$withval" + fi + ], + [want_boost="yes"]) + + +AC_ARG_WITH([boost-libdir], + AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), + [ + if test -d $withval + then + ac_boost_lib_path="$withval" + else + AC_MSG_ERROR(--with-boost-libdir expected directory name) + fi + ], + [ac_boost_lib_path=""] +) + +if test "x$want_boost" = "xyes"; then + boost_lib_version_req=ifelse([$1], ,1.20.0,$1) + boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` + boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` + boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` + boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + if test "x$boost_lib_version_req_sub_minor" = "x" ; then + boost_lib_version_req_sub_minor="0" + fi + WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` + AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) + succeeded=no + + libsubdir="lib" + if test "$(uname -m)" = "x86_64"; then + libsubdir="lib64" + fi + + dnl first we check the system location for boost libraries + dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl or if you install boost with RPM + if test "$ac_boost_path" != ""; then + BOOST_LDFLAGS="-L$ac_boost_path/$libsubdir" + BOOST_CPPFLAGS="-I$ac_boost_path/include" + elif test "$cross_compiling" != yes; then + for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then + BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + break; + fi + done + fi + + dnl overwrite ld flags if we have required special directory with + dnl --with-boost-libdir parameter + if test "$ac_boost_lib_path" != ""; then + BOOST_LDFLAGS="-L$ac_boost_lib_path" + fi + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_REQUIRE([AC_PROG_CXX]) + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include <boost/version.hpp> + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + + + + dnl if we found no boost with system layout we search for boost libraries + dnl built and installed without the --layout=system option or for a staged(not installed) version + if test "x$succeeded" != "xyes"; then + _version=0 + if test "$ac_boost_path" != ""; then + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + fi + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + done + fi + else + if test "$cross_compiling" != yes; then + for ac_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + best_path=$ac_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + if test "$ac_boost_lib_path" = "" + then + BOOST_LDFLAGS="-L$best_path/$libsubdir" + fi + fi + + if test "x$BOOST_ROOT" != "x"; then + if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then + version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` + stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` + stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` + V_CHECK=`expr $stage_version_shorten \>\= $_version` + if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) + BOOST_CPPFLAGS="-I$BOOST_ROOT" + BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + fi + fi + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include <boost/version.hpp> + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + fi + + if test "$succeeded" != "yes" ; then + if test "$_version" = "0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]]) + else + AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) + fi + # execute ACTION-IF-NOT-FOUND (if present): + ifelse([$3], , :, [$3]) + else + AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_LDFLAGS) + AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) + # execute ACTION-IF-FOUND (if present): + ifelse([$2], , :, [$2]) + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" +fi + +]) diff --git a/config/ax_boost_thread.m4 b/config/ax_boost_thread.m4 new file mode 100644 index 000000000..7393b2c01 --- /dev/null +++ b/config/ax_boost_thread.m4 @@ -0,0 +1,144 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_boost_thread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_THREAD +# +# DESCRIPTION +# +# Test for Thread library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# <http://randspringer.de/boost/index.html>. +# +# This macro calls: +# +# AC_SUBST(BOOST_THREAD_LIB) +# +# And sets: +# +# HAVE_BOOST_THREAD +# +# LICENSE +# +# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2009 Michael Tindal +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +AC_DEFUN([AX_BOOST_THREAD], +[ + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_thread_lib="" + else + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Thread library is available, + ax_cv_boost_thread, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + + if test "x$build_os" = "xsolaris" ; then + CXXFLAGS="-pthreads $CXXFLAGS" + elif test "x$build_os" = "xming32" ; then + CXXFLAGS="-mthreads $CXXFLAGS" + else + CXXFLAGS="-pthread $CXXFLAGS" + fi + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]], + [[boost::thread_group thrds; + return 0;]]), + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + if test "x$build_os" = "xsolaris" ; then + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + elif test "x$build_os" = "xming32" ; then + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + else + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + fi + + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + case "x$build_os" in + *bsd* ) + LDFLAGS="-pthread $LDFLAGS" + break; + ;; + esac + if test "x$ax_boost_user_thread_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_thread*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_thread.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_thread*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_thread.*\)\.a*$;\1;'`; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + if test "x$link_thread" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_thread*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_thread.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_thread*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_thread.*\)\.a*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + + fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + case "x$build_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + esac + + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..3076fde5e --- /dev/null +++ b/configure.ac @@ -0,0 +1,36 @@ +# +# Copyright 2010 Ettus Research LLC +# + +################################################## +## Setup Autotools +################################################## +AC_PREREQ(2.60) +AC_INIT +AM_INIT_AUTOMAKE(usrp_uhd, 0) + +################################################## +## Check Libs +################################################## +AC_PROG_CXX +LT_INIT +AX_BOOST_BASE([1.36]) +AX_BOOST_THREAD + +################################################## +## Check Programs +################################################## +AC_PATH_PROG(SED, sed) +AC_PATH_PROG(PYTHON, python) + +################################################## +## Create Files +################################################## +AC_CONFIG_FILES([ \ + Makefile \ + usrp_uhd/usrp_uhd.pc \ + usrp_uhd/Makefile \ + usrp_uhd/include/Makefile \ + usrp_uhd/lib/Makefile \ +]) +AC_OUTPUT diff --git a/usrp_uhd/.gitignore b/usrp_uhd/.gitignore new file mode 100644 index 000000000..2cc79dbab --- /dev/null +++ b/usrp_uhd/.gitignore @@ -0,0 +1,3 @@ +/Makefile +/Makefile.in +/usrp_uhd.pc diff --git a/usrp_uhd/Makefile.am b/usrp_uhd/Makefile.am new file mode 100644 index 000000000..c218af41a --- /dev/null +++ b/usrp_uhd/Makefile.am @@ -0,0 +1,13 @@ +# +# Copyright 2010 Ettus Research LLC +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = include lib + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = usrp_uhd.pc + +EXTRA_DIST = \ + usrp_uhd.pc.in diff --git a/usrp_uhd/include/.gitignore b/usrp_uhd/include/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/usrp_uhd/include/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/usrp_uhd/include/Makefile.am b/usrp_uhd/include/Makefile.am new file mode 100644 index 000000000..b5d09b431 --- /dev/null +++ b/usrp_uhd/include/Makefile.am @@ -0,0 +1,14 @@ +# +# Copyright 2010 Ettus Research LLC +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = + +usrp_uhd_includedir = $(includedir) + +usrp_uhd_include_HEADERS = \ + usrp_uhd.hpp \ + usrp_uhd/usrp_addr.hpp \ + usrp_uhd/wax.hpp diff --git a/usrp_uhd/include/usrp_uhd.hpp b/usrp_uhd/include/usrp_uhd.hpp new file mode 100644 index 000000000..6bf97a5a4 --- /dev/null +++ b/usrp_uhd/include/usrp_uhd.hpp @@ -0,0 +1,43 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#ifndef INCLUDED_USRP_UHD_HPP +#define INCLUDED_USRP_UHD_HPP + +#include <usrp_uhd/usrp_addr.hpp> +#include <usrp_uhd/wax.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <vector> +#include <sys/uio.h> + +namespace usrp{ + + class uhd{ + + public: + typedef boost::shared_ptr<uhd> sptr; + typedef boost::function<bool(void *data, size_t len)> recv_hdlr_t; + uhd(usrp_addr_t usrp_addr); + ~uhd(void); + + //the io interface + void send(const std::vector<iovec> &iovs); + void send(void* data, size_t len); //wrapper + void recv(const recv_hdlr_t &recv_hdlr); + void recv(void* &data, size_t &len); //wrapper + + //connect dsps and subdevs + void connect(const wax::type &src, const wax::type &sink); + + //the properties interface + wax::proxy props(void); + + private: + wax::type d_mboard; + }; + +} //namespace usrp + +#endif /* INCLUDED_USRP_UHD_HPP */ diff --git a/usrp_uhd/include/usrp_uhd/usrp_addr.hpp b/usrp_uhd/include/usrp_uhd/usrp_addr.hpp new file mode 100644 index 000000000..e8c282288 --- /dev/null +++ b/usrp_uhd/include/usrp_uhd/usrp_addr.hpp @@ -0,0 +1,90 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#ifndef INCLUDED_USRP_ADDR_HPP +#define INCLUDED_USRP_ADDR_HPP + +#include <string> +#include <iostream> +#include <netinet/ether.h> +#include <arpa/inet.h> + +namespace usrp{ + + /*! + * Wrapper for an ethernet mac address. + * Provides conversion between string and binary formats. + */ + struct mac_addr_t{ + struct ether_addr d_mac_addr; + mac_addr_t(const std::string &str = "00:00:00:00:00:00"); + std::string to_string(void) const; + }; + + /*! + * Wrapper for an ipv4 address. + * Provides conversion between string and binary formats. + */ + struct ip_addr_t{ + struct in_addr d_ip_addr; + ip_addr_t(const std::string &str = "0.0.0.0"); + std::string to_string(void) const; + }; + + /*! + * Possible usrp mboard interface types. + */ + enum usrp_addr_type_t{ + USRP_ADDR_TYPE_AUTO, + USRP_ADDR_TYPE_VIRTUAL, + USRP_ADDR_TYPE_USB, + USRP_ADDR_TYPE_ETH, + USRP_ADDR_TYPE_UDP, + USRP_ADDR_TYPE_GPMC + }; + + /*! + * Structure to hold properties that identify a usrp mboard. + */ + struct usrp_addr_t{ + usrp_addr_type_t type; + struct{ + size_t num_rx_dsps; + size_t num_tx_dsps; + size_t num_dboards; + } virtual_args; + struct{ + uint16_t vendor_id; + uint16_t product_id; + } usb_args; + struct{ + std::string ifc; + mac_addr_t mac_addr; + } eth_args; + struct{ + ip_addr_t ip_addr; + } udp_args; + struct{ + //TODO unknown for now + } gpmc_args; + + /*! + * \brief Convert a usrp usrp_addr_t into a string representation + */ + std::string to_string(void) const; + + /*! + * \brief Default constructor to initialize the usrp_addr_t struct + */ + usrp_addr_t(usrp_addr_type_t usrp_addr_type = USRP_ADDR_TYPE_AUTO); + }; + +} //namespace usrp + +//ability to use types with stream operators +std::ostream& operator<<(std::ostream &os, const usrp::usrp_addr_t &x); +std::ostream& operator<<(std::ostream &os, const usrp::mac_addr_t &x); +std::ostream& operator<<(std::ostream &os, const usrp::ip_addr_t &x); + +#endif /* INCLUDED_USRP_ADDR_HPP */ diff --git a/usrp_uhd/include/usrp_uhd/wax.hpp b/usrp_uhd/include/usrp_uhd/wax.hpp new file mode 100644 index 000000000..9d32314f7 --- /dev/null +++ b/usrp_uhd/include/usrp_uhd/wax.hpp @@ -0,0 +1,129 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#ifndef INCLUDED_WAX_HPP +#define INCLUDED_WAX_HPP + +#include <boost/any.hpp> +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/pointer_cast.hpp> +#include <iostream> + +/*! + * WAX - it's a metaphor! + * + * The WAX framework allows object to have generic/anytype properties. + * These properties can be addressed through generic/anytype identifiers. + * A property of a WAX object may even be another WAX object. + * + * When a property is a WAX object, the returned value must be an obj pointer. + * A WAX object provides two types of pointers: obj::ptr and obj::sptr. + * The choice of pointer vs smart pointer depends on the owner of the memory. + * + * Proprties may be referenced though the [] overloaded operator. + * The [] operator returns a special proxy that allows for assigment. + * Also, the [] operators may be chained as in the folowing examples: + * my_obj[prop1][prop2][prop3] = value + * value = my_obj[prop1][prop2][prop3] + * + * Any value returned from an access operation is of wax::type. + * To use this value, it must be cast with wax::cast<new_type>(value). + */ + +namespace wax{ + + //general typedefs + typedef boost::any type; + typedef boost::bad_any_cast bad_cast; + + //dummy class declarations + class obj; class proxy; + + /*! + * WAX object base class: + * A wax object subclass should override the set and get methods. + * The magic of operator chaining is handled by the [] operator. + */ + class obj{ + public: + //obj pointer typedefs + typedef boost::shared_ptr<obj> sptr; + typedef obj* ptr; + + //cast derived pointer to obj base class pointer + template <class T> static sptr cast(boost::shared_ptr<T> r){ + return boost::static_pointer_cast<obj>(r); + } + template <class T> static ptr cast(T *r){ + return dynamic_cast<ptr>(r); + } + + //structors + obj(void); + virtual ~obj(void); + + //public interface + proxy operator[](const type &key); + + private: + //private interface + virtual void get(const type &key, type &val) = 0; + virtual void set(const type &key, const type &val) = 0; + }; + + /*! + * WAX proxy class: + * Allows the obj [] operator to return a proxy result. + * This result can be assigned to via the = operator. + * Or this result can be called again with the [] operator. + */ + class proxy{ + public: + //destructors + ~proxy(void); + + //overloaded + type operator()(void); + proxy operator[](const type &key); + proxy operator=(const type &key); + + private: + //typedefs for callables from the object that built this proxy + typedef boost::function<void(const type &)> setter_t; + typedef boost::function<void(type &)> getter_t; + + //private contructor + proxy(getter_t, setter_t); + //access to private contructor + friend proxy obj::operator[](const type &key); + + getter_t d_getter; + setter_t d_setter; + }; + + /*! + * Cast a wax::type into the desired type + * Usage wax::cast<new_type>(my_value). + * + * \param val the any type to cast + * \return data of the desired type + * \throw wax::bad_cast when the cast fails + */ + template<typename T> T cast(const type & val){ + //special case to handle the proxy + if (val.type() == typeid(proxy)){ + return cast<T>(boost::any_cast<proxy>(val)()); + } + //do the type cast + return boost::any_cast<T>(val); + } + +} //namespace wax + +//ability to use types with stream operators +std::ostream& operator<<(std::ostream &os, const wax::type &x); + +#endif /* INCLUDED_WAX_HPP */ diff --git a/usrp_uhd/lib/.gitignore b/usrp_uhd/lib/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/usrp_uhd/lib/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/usrp_uhd/lib/Makefile.am b/usrp_uhd/lib/Makefile.am new file mode 100644 index 000000000..09e15301b --- /dev/null +++ b/usrp_uhd/lib/Makefile.am @@ -0,0 +1,25 @@ +# +# Copyright 2010 Ettus Research LLC +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = + +AM_CPPFLAGS = \ + $(USRP_UHD_INCLUDES) \ + $(BOOST_CPPFLAGS) + +lib_LTLIBRARIES = \ + libusrp_uhd.la + +libusrp_uhd_la_SOURCES = \ + usrp_addr.cpp \ + usrp_uhd.cpp \ + wax.cpp + +libusrp_uhd_la_LIBADD = \ + $(BOOST_LDFLAGS) \ + $(BOOST_THREAD_LIB) + +noinst_HEADERS = diff --git a/usrp_uhd/lib/usrp_addr.cpp b/usrp_uhd/lib/usrp_addr.cpp new file mode 100644 index 000000000..ddae7cd80 --- /dev/null +++ b/usrp_uhd/lib/usrp_addr.cpp @@ -0,0 +1,116 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#include <usrp_uhd/usrp_addr.hpp> +#include <sstream> +#include <cstring> +#include <cstdio> +#include <stdexcept> + +//----------------------- u2 mac addr wrapper ------------------------// +usrp::mac_addr_t::mac_addr_t(const std::string &str){ + //ether_aton_r(str.c_str(), &d_mac_addr); + bool good = false; + char p[6] = {0x00, 0x50, 0xC2, 0x85, 0x30, 0x00}; // Matt's IAB + + switch (str.size()){ + case 5: + good = sscanf(str.c_str(), "%hhx:%hhx", &p[4], &p[5]) == 2; + break; + case 17: + good = sscanf(str.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]) == 6; + break; + } + + if (not good) throw std::runtime_error("Invalid mac address: " + str); + memcpy(&d_mac_addr, p, sizeof(d_mac_addr)); +} + +std::string usrp::mac_addr_t::to_string(void) const{ + char addr_buf[128]; + //ether_ntoa_r(&d_mac_addr, addr_buf); + const uint8_t *p = reinterpret_cast<const uint8_t *>(&d_mac_addr); + sprintf(addr_buf, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return std::string(addr_buf); +} + +std::ostream& operator<<(std::ostream &os, const usrp::mac_addr_t &x){ + os << x.to_string(); + return os; +} + +//----------------------- u2 ipv4 wrapper ----------------------------// +usrp::ip_addr_t::ip_addr_t(const std::string &str){ + int ret = inet_pton(AF_INET, str.c_str(), &d_ip_addr); + if (ret == 0) throw std::runtime_error("Invalid ip address: " + str); +} + +std::string usrp::ip_addr_t::to_string(void) const{ + char addr_buf[128]; + inet_ntop(AF_INET, &d_ip_addr, addr_buf, INET_ADDRSTRLEN); + return std::string(addr_buf); +} + +std::ostream& operator<<(std::ostream &os, const usrp::ip_addr_t &x){ + os << x.to_string(); + return os; +} + +//----------------------- usrp usrp_addr_t wrapper -------------------------// +usrp::usrp_addr_t::usrp_addr_t(usrp_addr_type_t usrp_addr_type){ + type = usrp_addr_type; + virtual_args.num_rx_dsps = 0; + virtual_args.num_tx_dsps = 0; + virtual_args.num_dboards = 0; + usb_args.vendor_id = 0xffff; + usb_args.product_id = 0xffff; + eth_args.ifc = "eth0"; + eth_args.mac_addr = mac_addr_t("ff:ff:ff:ff:ff:ff"); + udp_args.ip_addr = ip_addr_t("255.255.255.255"); +} + +std::string usrp::usrp_addr_t::to_string(void) const{ + std::stringstream out; + out << "USRP Type: "; + switch(type){ + case USRP_ADDR_TYPE_AUTO: + out << "Automatic" << std::endl; + break; + case USRP_ADDR_TYPE_VIRTUAL: + out << "Virtual" << std::endl; + out << "Num RX DSPs: " << virtual_args.num_rx_dsps << std::endl; + out << "Num TX DSPs: " << virtual_args.num_rx_dsps << std::endl; + out << "Num dboards: " << virtual_args.num_dboards << std::endl; + break; + case USRP_ADDR_TYPE_USB: + out << "USB Port" << std::endl; + out << "Vendor ID: 0x" << std::hex << usb_args.vendor_id << std::endl; + out << "Product ID: 0x" << std::hex << usb_args.product_id << std::endl; + break; + case USRP_ADDR_TYPE_ETH: + out << "Raw Ethernet" << std::endl; + out << "Interface: " << eth_args.ifc << std::endl; + out << "MAC Addr: " << eth_args.mac_addr << std::endl; + break; + case USRP_ADDR_TYPE_UDP: + out << "UDP Socket" << std::endl; + out << "IP Addr: " << udp_args.ip_addr << std::endl; + break; + case USRP_ADDR_TYPE_GPMC: + out << "GPMC" << std::endl; + break; + default: + out << "Unknown" << std::endl; + } + out << std::endl; + return out.str(); +} + +std::ostream& operator<<(std::ostream &os, const usrp::usrp_addr_t &x) +{ + os << x.to_string(); + return os; +} diff --git a/usrp_uhd/lib/usrp_uhd.cpp b/usrp_uhd/lib/usrp_uhd.cpp new file mode 100644 index 000000000..6dd9bee7b --- /dev/null +++ b/usrp_uhd/lib/usrp_uhd.cpp @@ -0,0 +1,10 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#include <usrp_uhd.hpp> + +using namespace usrp; + +uhd::uhd(usrp_addr_t usrp_addr){} +uhd::~uhd(void){} diff --git a/usrp_uhd/lib/wax.cpp b/usrp_uhd/lib/wax.cpp new file mode 100644 index 000000000..888e581f3 --- /dev/null +++ b/usrp_uhd/lib/wax.cpp @@ -0,0 +1,71 @@ +// +// Copyright 2010 Ettus Research LLC +// + +#include <usrp_uhd/wax.hpp> +#include <stdexcept> +#include <boost/bind.hpp> +#include <boost/format.hpp> + +/*********************************************************************** + * WAX Object + **********************************************************************/ +wax::obj::obj(void){ + /* NOP */ +} + +wax::obj::~obj(void){ + /* NOP */ +} + +wax::proxy wax::obj::operator[](const type &key){ + return proxy( + boost::bind(&obj::get, this, key, _1), + boost::bind(&obj::set, this, key, _1) + ); +} + +/*********************************************************************** + * WAX Proxy + **********************************************************************/ +wax::proxy::proxy(wax::proxy::getter_t getter, wax::proxy::setter_t setter) +: d_getter(getter), d_setter(setter){ + /* NOP */ +} + +wax::proxy::~proxy(void){ + /* NOP */ +} + +wax::proxy wax::proxy::operator[](const type &key){ + type val((*this)()); + //check if its a regular pointer and call + if (val.type() == typeid(obj::ptr)){ + return (*cast<obj::ptr>(val))[key]; + } + //check if its a smart pointer and call + if (val.type() == typeid(obj::sptr)){ + return (*cast<obj::sptr>(val))[key]; + } + //unknown type + throw std::runtime_error("cannot use [] on non wax::obj pointer"); +} + +wax::proxy wax::proxy::operator=(const type &val){ + d_setter(val); + return *this; +} + +wax::type wax::proxy::operator()(void){ + type val; + d_getter(val); + return val; +} + +/*********************************************************************** + * WAX Type + **********************************************************************/ +std::ostream& operator<<(std::ostream &os, const wax::type &x){ + os << boost::format("WAX type (%s)") % x.type().name(); + return os; +} diff --git a/usrp_uhd/usrp_uhd.pc.in b/usrp_uhd/usrp_uhd.pc.in new file mode 100644 index 000000000..18194a741 --- /dev/null +++ b/usrp_uhd/usrp_uhd.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: usrp_uhd +Description: Universal Software Radio Peripheral - Unified Hardware Driver +Requires: +Version: @VERSION@ +Libs: -L${libdir} -lusrp_uhd +Cflags: -I${includedir} |