commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 14/148: Created transport abstraction. Impl


From: git
Subject: [Commit-gnuradio] [gnuradio] 14/148: Created transport abstraction. Implemented ethernet transport for control. Control transport works in usrp impl. Needs a lot of cleanup.
Date: Mon, 15 Aug 2016 00:47:20 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

nwest pushed a commit to annotated tag old_usrp_devel_udp
in repository gnuradio.

commit c49d96df6a38a31df98b67b2d20d65b4a448869f
Author: Josh Blum <address@hidden>
Date:   Tue Nov 3 19:49:57 2009 -0800

    Created transport abstraction.
    Implemented ethernet transport for control.
    Control transport works in usrp impl.
    Needs a lot of cleanup.
---
 usrp2/host/lib/Makefile.am   |  4 +-
 usrp2/host/lib/transport.cc  | 82 +++++++++++++++++++++++++++++++++++++++++
 usrp2/host/lib/transport.h   | 79 +++++++++++++++++++++++++++++++++++++++
 usrp2/host/lib/usrp2.cc      | 88 +++++++++++++++++++++++++++++++++++++++++++-
 usrp2/host/lib/usrp2_impl.cc | 33 +++++++++--------
 usrp2/host/lib/usrp2_impl.h  | 11 ++++--
 6 files changed, 275 insertions(+), 22 deletions(-)

diff --git a/usrp2/host/lib/Makefile.am b/usrp2/host/lib/Makefile.am
index 0c3e180..1371ab0 100644
--- a/usrp2/host/lib/Makefile.am
+++ b/usrp2/host/lib/Makefile.am
@@ -1,5 +1,5 @@
 #
-# Copyright 2007,2008 Free Software Foundation, Inc.
+# Copyright 2007,2008,2009 Free Software Foundation, Inc.
 #
 # 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
@@ -41,6 +41,7 @@ libusrp2_la_SOURCES = \
        open_usrp2_socket.cc \
        pktfilter.cc \
        ring.cc \
+       transport.cc \
        rx_nop_handler.cc \
        rx_sample_handler.cc \
        strtod_si.c \
@@ -60,5 +61,6 @@ noinst_HEADERS = \
        open_usrp2_socket.h \
        pktfilter.h \
        ring.h \
+       transport.h \
        usrp2_bytesex.h \
        usrp2_impl.h
diff --git a/usrp2/host/lib/transport.cc b/usrp2/host/lib/transport.cc
new file mode 100644
index 0000000..325e829
--- /dev/null
+++ b/usrp2/host/lib/transport.cc
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "transport.h"
+#include <stdexcept>
+
+static void nop_cb(void *buff, size_t len){
+    //NOP
+}
+
+usrp2::transport::transport(const std::string &type_str){
+    d_cb = nop_cb;
+    d_type_str = type_str;
+    d_running = false;
+}
+
+usrp2::transport::~transport(){
+    if (d_running) stop();
+}
+
+void usrp2::transport::init(){
+    //NOP
+}
+
+void usrp2::transport::start(){
+    if (d_running){
+        throw std::runtime_error("usrp2::transport for" + d_type_str + " 
already started\n");
+    }
+    d_thread = new boost::thread(boost::bind(&usrp2::transport::run, this));
+}
+
+void usrp2::transport::stop(){
+    if (not d_running){
+        throw std::runtime_error("usrp2::transport for" + d_type_str + " 
already stopped\n");
+    }
+    d_running = false;
+    d_thread->join();
+}
+
+void usrp2::transport::run(){
+    init();
+    d_running = true;
+    void *buff;
+    while (d_running){
+        try{
+            // call recv to get a pointer into memory
+            // pass the buffer into the callback
+            int len = recv(&buff);
+            if (len > 0) d_cb(buff, len);
+        //catch thread interrupts from join, sleep, etc
+        //the running condition will be re-checked
+        }catch(boost::thread_interrupted const &){}
+    }
+}
+
+int usrp2::transport::send(const void *buff, int len){
+    return -1; //NOP
+}
+
+int usrp2::transport::recv(void **buff){
+    *buff = NULL;
+    return -1; //NOP
+}
diff --git a/usrp2/host/lib/transport.h b/usrp2/host/lib/transport.h
new file mode 100644
index 0000000..c6a42f8
--- /dev/null
+++ b/usrp2/host/lib/transport.h
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * 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_TRANSPORT_H
+#define INCLUDED_TRANSPORT_H
+
+#include <boost/thread.hpp>
+#include <cstring>
+
+namespace usrp2 {
+
+  class transport {
+  public:
+    typedef boost::function<void(void*, size_t)> callback_t;
+  private:
+    std::string              d_type_str;
+    volatile bool            d_running;
+    boost::thread            *d_thread;
+    callback_t               d_cb;
+    void run();
+  public:
+    /*!
+     * \brief create a new transport
+     * The callback takes a void * pointer and a length in bytes.
+     * \param type_str a descriptive string
+     */
+    transport(const std::string &type_str);
+    ~transport();
+    /*!
+     * \brief Set the callback
+     * \param cb the callback created by boost::bind
+     */
+    void set_callback(callback_t cb){d_cb=cb;}
+    /*!
+     * \brief create a new thread for receiving
+     */
+    void start();
+    /*!
+     * \brief stop and join the current thread
+     */
+    void stop();
+    /*!
+     * \brief called from thread on init (override in a subclass)
+     * Purpose: to have a thread initialization hook.
+     */
+    virtual void init();
+    /*!
+     * \brief send the contents of the buffer (override in a subclass)
+     * \param buff a pointer into memory
+     * \param len the length of the buffer in bytes
+     * \return the number of bytes sent, -1 for error
+     */
+    virtual int send(const void *buff, int len);
+    /*!
+     * \brief receive data into the buffer (override in a subclass)
+     * \param buff a pointer to a pointer into memory
+     * \return the number of bytes received, -1 for error
+     */
+    virtual int recv(void **buff);
+  };
+  
+} // namespace usrp2
+
+#endif /* INCLUDED_TRANSPORT_H */
diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc
index a2a9ecc..0ed854a 100644
--- a/usrp2/host/lib/usrp2.cc
+++ b/usrp2/host/lib/usrp2.cc
@@ -29,6 +29,91 @@
 #include <stdexcept>
 #include <cstdio>
 
+  //FIXME this is the third instance of this function, find it a home
+  static bool
+  parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
+  {
+    p->addr[0] = 0x00;         // Matt's IAB
+    p->addr[1] = 0x50;
+    p->addr[2] = 0xC2;
+    p->addr[3] = 0x85;
+    p->addr[4] = 0x30;
+    p->addr[5] = 0x00;
+    
+    int len = s.size();
+    
+    switch (len){
+      
+    case 5:
+      return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2;
+      
+    case 17:
+      return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+                   &p->addr[0], &p->addr[1], &p->addr[2],
+                   &p->addr[3], &p->addr[4], &p->addr[5]) == 6;
+    default:
+      return false;
+    }
+  }
+
+// ----------------------------------------------------------------
+//        Ethernet transport classes for data and control
+// ----------------------------------------------------------------
+#include "transport.h"
+#include "ethernet.h"
+#include "pktfilter.h"
+class eth_ctrl_transport: public usrp2::transport{
+  private:
+    uint8_t              d_buff[1500]; //FIXME use MTU
+    usrp2::ethernet      *d_eth_ctrl;  // unbuffered control frames
+    usrp2::pktfilter     *d_pf_ctrl;
+
+  public:
+  eth_ctrl_transport(const std::string &ifc, usrp2::props *p) : 
usrp2::transport("ethernet control"){
+
+    //create raw ethernet device
+    d_eth_ctrl = new usrp2::ethernet();
+    if (!d_eth_ctrl->open(ifc, htons(U2_CTRL_ETHERTYPE)))
+      throw std::runtime_error("Unable to open/register USRP2 control 
protocol");
+
+    //extract mac addr
+    u2_mac_addr_t usrp_mac;
+    parse_mac_addr(p->addr, &usrp_mac);
+
+    //create and attach packet filter
+    d_pf_ctrl = 
usrp2::pktfilter::make_ethertype_inbound_target(U2_CTRL_ETHERTYPE, (const 
unsigned char*)&(usrp_mac.addr));
+    if (!d_pf_ctrl || !d_eth_ctrl->attach_pktfilter(d_pf_ctrl))
+        throw std::runtime_error("Unable to attach packet filter for control 
packets.");
+
+    start(); //start thread now
+  }
+
+  ~eth_ctrl_transport(){
+    delete d_pf_ctrl;
+    d_eth_ctrl->close();
+    delete d_eth_ctrl;
+  }
+
+  int send(const void *buff, int len){
+    return d_eth_ctrl->write_packet(buff, len);
+  }
+
+  int recv(void **buff){
+    int recv_len = d_eth_ctrl->read_packet_dont_block(d_buff, sizeof(d_buff));
+    if (recv_len > 0){
+        *buff = d_buff;
+        return recv_len;
+    }
+    boost::this_thread::sleep(gruel::get_new_timeout(0.05)); //50ms timeout
+    return 0; //nothing yet
+  }
+
+};
+
+
+// ----------------------------------------------------------------
+//        The USRP2 class wrapper for impl
+// ----------------------------------------------------------------
 namespace usrp2 {
 
   // --- Table of weak pointers to usrps we know about ---
@@ -144,9 +229,8 @@ namespace usrp2 {
 
   // Private constructor.  Sole function is to create an impl.
   usrp2::usrp2(const std::string &ifc, props *p, size_t rx_bufsize)
-    : d_impl(new usrp2::impl(ifc, p, rx_bufsize))
   {
-    // NOP
+    d_impl = std::auto_ptr<impl>(new usrp2::impl(ifc, p, rx_bufsize, new 
eth_ctrl_transport(ifc, p)));
   }
   
   // Public class destructor.  d_impl will auto-delete.
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
index 1caa071..e9bb4b8 100644
--- a/usrp2/host/lib/usrp2_impl.cc
+++ b/usrp2/host/lib/usrp2_impl.cc
@@ -129,7 +129,7 @@ namespace usrp2 {
   }
 
 
-  usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize)
+  usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize, 
transport *ctrl_transport)
     : d_eth_data(new eth_buffer(rx_bufsize)),
       d_eth_ctrl(new ethernet()),
       d_pf_data(0), 
@@ -150,12 +150,15 @@ namespace usrp2 {
       d_rx_decim(0),
       d_dont_enqueue(true),
       d_ctrl_running(false),
-      d_data_running(false)
+      d_data_running(false),
+      d_ctrl_transport(ctrl_transport)
   {
+    
d_ctrl_transport->set_callback(boost::bind(&usrp2::impl::handle_control_packet, 
this, _1, _2));
+
     if (!d_eth_data->open(ifc, htons(U2_DATA_ETHERTYPE)))
       throw std::runtime_error("Unable to open/register USRP2 data protocol");
-    if (!d_eth_ctrl->open(ifc, htons(U2_CTRL_ETHERTYPE)))
-      throw std::runtime_error("Unable to open/register USRP2 control 
protocol");
+    //if (!d_eth_ctrl->open(ifc, htons(U2_CTRL_ETHERTYPE)))
+    //  throw std::runtime_error("Unable to open/register USRP2 control 
protocol");
 
     d_addr = p->addr;
 
@@ -165,9 +168,9 @@ namespace usrp2 {
     d_pf_data = pktfilter::make_ethertype_inbound_target(U2_DATA_ETHERTYPE, 
(const unsigned char*)&(usrp_mac.addr));
     if (!d_pf_data || !d_eth_data->attach_pktfilter(d_pf_data))
       throw std::runtime_error("Unable to attach packet filter for data 
packets.");
-    d_pf_ctrl = pktfilter::make_ethertype_inbound_target(U2_CTRL_ETHERTYPE, 
(const unsigned char*)&(usrp_mac.addr));
-    if (!d_pf_ctrl || !d_eth_ctrl->attach_pktfilter(d_pf_ctrl))
-      throw std::runtime_error("Unable to attach packet filter for control 
packets.");
+    //d_pf_ctrl = pktfilter::make_ethertype_inbound_target(U2_CTRL_ETHERTYPE, 
(const unsigned char*)&(usrp_mac.addr));
+    //if (!d_pf_ctrl || !d_eth_ctrl->attach_pktfilter(d_pf_ctrl))
+    //  throw std::runtime_error("Unable to attach packet filter for control 
packets.");
     
     if (USRP2_IMPL_DEBUG)
       std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl;
@@ -175,7 +178,7 @@ namespace usrp2 {
     memset(d_pending_replies, 0, sizeof(d_pending_replies));
 
     start_data_thread();
-    start_ctrl_thread();
+    //start_ctrl_thread();
 
     // In case the USRP2 was left streaming RX
     // FIXME: only one channel right now
@@ -231,14 +234,14 @@ namespace usrp2 {
   {
     //thread cleanup
     stop_data_thread();
-    stop_ctrl_thread();
+    //stop_ctrl_thread();
     //socket cleanup
     delete d_pf_data;
-    delete d_pf_ctrl;
+    //delete d_pf_ctrl;
     d_eth_data->close();
     delete d_eth_data;
-    d_eth_ctrl->close();
-    delete d_eth_ctrl;
+    //d_eth_ctrl->close();
+    //delete d_eth_ctrl;
 
     if (USRP2_IMPL_DEBUG) {
       std::cerr << std::endl
@@ -341,7 +344,7 @@ namespace usrp2 {
       len = sizeof(tmp);
     }
 
-    return d_eth_ctrl->write_packet(cmd, len) >= 0;
+    return d_ctrl_transport->send(cmd, len) >= 0;
   }
 
   bool
@@ -363,7 +366,7 @@ namespace usrp2 {
   //        Background loop for handling control packets
   // ----------------------------------------------------------------
 
-  void
+  /*void
   usrp2::impl::start_ctrl_thread()
   {
     d_ctrl_thread = new 
boost::thread(boost::bind(&usrp2::impl::run_ctrl_thread, this));
@@ -387,7 +390,7 @@ namespace usrp2 {
       if (ctrl_recv_len > 0) handle_control_packet(buff, ctrl_recv_len);
       else boost::this_thread::sleep(gruel::get_new_timeout(0.05)); //50ms 
timeout
     }
-  }
+  }*/
 
   // ----------------------------------------------------------------
   //        Background loop for handling data packets
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
index 594a4bf..50cb78a 100644
--- a/usrp2/host/lib/usrp2_impl.h
+++ b/usrp2/host/lib/usrp2_impl.h
@@ -27,6 +27,7 @@
 #include <boost/thread.hpp>
 #include "control.h"
 #include "ring.h"
+#include "transport.h"
 #include <string>
 
 #define MAX_SUBPKT_LEN 252
@@ -120,9 +121,9 @@ namespace usrp2 {
     //control thread stuff
     volatile bool d_ctrl_running;
     boost::thread *d_ctrl_thread;
-    void start_ctrl_thread();
-    void stop_ctrl_thread();
-    void run_ctrl_thread();
+    //void start_ctrl_thread();
+    //void stop_ctrl_thread();
+    //void run_ctrl_thread();
 
     //data thread stuff
     volatile bool d_data_running; // TODO: multistate if needed
@@ -131,8 +132,10 @@ namespace usrp2 {
     void stop_data_thread();
     void run_data_thread();
 
+    transport *d_ctrl_transport;
+
   public:
-    impl(const std::string &ifc, props *p, size_t rx_bufsize);
+    impl(const std::string &ifc, props *p, size_t rx_bufsize, transport 
*ctrl_transport);
     ~impl();
 
     std::string mac_addr() const { return d_addr; } // FIXME: convert from 
u2_mac_addr_t



reply via email to

[Prev in Thread] Current Thread [Next in Thread]