commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 45/148: Re-implemented find.cc with gruel a


From: git
Subject: [Commit-gnuradio] [gnuradio] 45/148: Re-implemented find.cc with gruel and eth_ctrl_transport class. Added constructor args to the eth control transport to set the timeout and target for the packet filter.
Date: Mon, 15 Aug 2016 00:47:23 +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 2ecc7c92ae901298fd71c80139403c1961896de4
Author: Josh Blum <address@hidden>
Date:   Thu Nov 19 15:29:01 2009 -0800

    Re-implemented find.cc with gruel and eth_ctrl_transport class.
    Added constructor args to the eth control transport to set the timeout and 
target for the packet filter.
---
 usrp2/host/lib/eth_ctrl_transport.cc |  45 ++++---
 usrp2/host/lib/eth_ctrl_transport.h  |  15 ++-
 usrp2/host/lib/find.cc               | 238 ++++++++++++++---------------------
 usrp2/host/lib/ring.cc               |   2 +-
 usrp2/host/lib/ring.h                |   2 +-
 usrp2/host/lib/transport.h           |   2 +-
 usrp2/host/lib/usrp2_impl.cc         |   6 +-
 usrp2/host/lib/usrp2_impl.h          |   4 +-
 8 files changed, 142 insertions(+), 172 deletions(-)

diff --git a/usrp2/host/lib/eth_ctrl_transport.cc 
b/usrp2/host/lib/eth_ctrl_transport.cc
index 7fd356d..7bc4a58 100644
--- a/usrp2/host/lib/eth_ctrl_transport.cc
+++ b/usrp2/host/lib/eth_ctrl_transport.cc
@@ -18,7 +18,8 @@
 
 #include "eth_ctrl_transport.h"
 
-usrp2::eth_ctrl_transport::eth_ctrl_transport(const std::string &ifc, 
u2_mac_addr_t mac) : transport("ethernet control"), d_mac(mac){
+usrp2::eth_ctrl_transport::eth_ctrl_transport(const std::string &ifc, 
u2_mac_addr_t mac, double timeout, bool target)
+ : transport("ethernet control"), d_mac(mac), d_buff(NULL), d_timeout(timeout){
 
     //create raw ethernet device
     d_eth_ctrl = new ethernet();
@@ -26,7 +27,8 @@ usrp2::eth_ctrl_transport::eth_ctrl_transport(const 
std::string &ifc, u2_mac_add
         throw std::runtime_error("Unable to open/register USRP2 control 
protocol");
 
     //create and attach packet filter
-    d_pf_ctrl = pktfilter::make_ethertype_inbound_target(U2_CTRL_ETHERTYPE, 
(const unsigned char*)&(d_mac.addr));
+    if (target) d_pf_ctrl = 
pktfilter::make_ethertype_inbound_target(U2_CTRL_ETHERTYPE, (const unsigned 
char*)&(d_mac.addr));
+    else        d_pf_ctrl = 
pktfilter::make_ethertype_inbound(U2_CTRL_ETHERTYPE, d_eth_ctrl->mac());
     if (!d_pf_ctrl || !d_eth_ctrl->attach_pktfilter(d_pf_ctrl))
         throw std::runtime_error("Unable to attach packet filter for control 
packets.");
 }
@@ -35,6 +37,7 @@ usrp2::eth_ctrl_transport::~eth_ctrl_transport(){
     delete d_pf_ctrl;
     d_eth_ctrl->close();
     delete d_eth_ctrl;
+    delete[] d_buff;
 }
 
 int usrp2::eth_ctrl_transport::sendv(const iovec *iov, size_t iovlen){
@@ -61,24 +64,34 @@ int usrp2::eth_ctrl_transport::sendv(const iovec *iov, 
size_t iovlen){
     for (size_t i = 0; i < all_iov_len-1; i++){
         num_bytes += all_iov[i].iov_len;
     }
-    //handle padding, must be at least 64 bytes
-    uint8_t padding[64];
+    //handle padding, must be at least minimum length
+    uint8_t padding[ethernet::MIN_PKTLEN];
+    memset(padding, 0, ethernet::MIN_PKTLEN);
     all_iov[all_iov_len-1].iov_base = padding;
-    all_iov[all_iov_len-1].iov_len = (num_bytes < 64) ? (64 - num_bytes) : 0;
+    all_iov[all_iov_len-1].iov_len = std::max(ethernet::MIN_PKTLEN-num_bytes, 
0);
     return d_eth_ctrl->write_packetv(all_iov, all_iov_len);
 }
 
+//helper function that deletes an array allocated by new
+//FIXME replace with the boost::lambda::delete_array
+static void delete_array(uint8_t *array){delete[] array;}
+
 std::vector<usrp2::sbuff::sptr> usrp2::eth_ctrl_transport::recv(){
-    //TODO perform multiple non blocking recvs and pack into sbs
-    int recv_len = d_eth_ctrl->read_packet_dont_block(d_buff, sizeof(d_buff));
-    //strip the ethernet headers from the buffer
-    if (recv_len > (signed)sizeof(u2_eth_packet_t)){
-        std::vector<sbuff::sptr> sbs;
-        sbs.push_back(sbuff::make(
-            d_buff + sizeof(u2_eth_packet_t),
-            recv_len - sizeof(u2_eth_packet_t)));
-        return sbs;
+    std::vector<sbuff::sptr> sbs;
+    for (size_t i = 0; i < max_buffs(); i++){
+        //allocate a new buffer and recv
+        if (d_buff == NULL) d_buff = new uint8_t[ethernet::MAX_PKTLEN];
+        int recv_len = d_eth_ctrl->read_packet_dont_block(d_buff, 
ethernet::MAX_PKTLEN);
+        //strip the ethernet headers from the buffer
+        if (recv_len > (signed)sizeof(u2_eth_packet_t)){
+            sbs.push_back(sbuff::make(
+                d_buff + sizeof(u2_eth_packet_t),
+                recv_len - sizeof(u2_eth_packet_t),
+                boost::bind(delete_array, d_buff)));
+            d_buff = NULL; //set to null to flag for a new allocation
+        } else break;
     }
-    boost::this_thread::sleep(gruel::get_new_timeout(0.05)); //50ms timeout
-    return std::vector<sbuff::sptr>(); //nothing yet
+    //if nothing was received, busy sleep to save cpu
+    if (sbs.size() == 0) 
boost::this_thread::sleep(gruel::get_new_timeout(d_timeout));
+    return sbs;
 }
diff --git a/usrp2/host/lib/eth_ctrl_transport.h 
b/usrp2/host/lib/eth_ctrl_transport.h
index 427e364..ad9b9ff 100644
--- a/usrp2/host/lib/eth_ctrl_transport.h
+++ b/usrp2/host/lib/eth_ctrl_transport.h
@@ -28,16 +28,27 @@ namespace usrp2{
 
     class eth_ctrl_transport: public transport{
     private:
-        uint8_t              d_buff[1500]; //FIXME use MTU
         ethernet      *d_eth_ctrl;  // unbuffered control frames
         pktfilter     *d_pf_ctrl;
         u2_mac_addr_t d_mac;
+        uint8_t       *d_buff;
+        double_t      d_timeout;
 
     public:
-        eth_ctrl_transport(const std::string &ifc, u2_mac_addr_t mac);
+        /*!
+         * \brief Create a new transport for the raw ethernet control
+         * When the target is true, the packet filter is setup for the usrp 
mac address.
+         * When the target is false, the packet filter is setup to ignore our 
mac address.
+         * \param ifc the ethernet device name
+         * \param mac the destination mac address
+         * \param timeout the timeout in seconds (default 50ms)
+         * \param target true for an inbound target
+         */
+        eth_ctrl_transport(const std::string &ifc, u2_mac_addr_t mac, double 
timeout=0.05, bool target = true);
         ~eth_ctrl_transport();
         int sendv(const iovec *iov, size_t iovlen);
         std::vector<sbuff::sptr> recv();
+        size_t max_buffs(){return 3;}
 };
 
 
diff --git a/usrp2/host/lib/find.cc b/usrp2/host/lib/find.cc
index b12aedb..6bd987c 100644
--- a/usrp2/host/lib/find.cc
+++ b/usrp2/host/lib/find.cc
@@ -22,158 +22,104 @@
 
 #include <usrp2_eth_packet.h>
 #include <usrp2/usrp2.h>
-#include <boost/scoped_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include "ethernet.h"
-#include "pktfilter.h"
+#include <boost/shared_ptr.hpp>
 #include <string.h>
 #include <iostream>
 #include <stdexcept>
 #include <cstdio>
+#include <gruel/thread.h>
+#include "eth_ctrl_transport.h"
 
-#define FIND_DEBUG 0
-
-// FIXME re-implement with eth_ctrl_transport 
-
-// FIXME move to gruel
-
-static struct timeval
-time_duration_to_timeval(boost::posix_time::time_duration delta)
-{
-  long total_us = delta.total_microseconds();
-  if (total_us < 0)
-    throw std::invalid_argument("duration_to_time: delta is negative");
-
-  struct timeval tv;
-  tv.tv_sec =  total_us / 1000000;
-  tv.tv_usec = total_us % 1000000;
-  return tv;
-}
-
-
-namespace usrp2 {
-
-  static props
-  reply_to_props(const op_id_reply_t *r)
-  {
-    const uint8_t *mac = (const uint8_t *)&r->addr;
-    char addr_buf[128];
-    snprintf(addr_buf, sizeof(addr_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
-            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-      
-    props p;
-    p.addr = std::string(addr_buf);  
-    p.hw_rev = ntohs(r->hw_rev);
-    memcpy(p.fpga_md5sum, r->fpga_md5sum, sizeof(p.fpga_md5sum));
-    memcpy(p.sw_md5sum, r->sw_md5sum, sizeof(p.sw_md5sum));
-    return p;
-  }
-
-  static void
-  read_replies(ethernet *enet, struct timeval timeout,
-              const std::string &target_addr, props_vector_t &result)
-  {
-    struct reply {
-      u2_eth_packet_t  h;
-      op_id_reply_t    op_id_reply;
-    };
-    
-    uint8_t pktbuf[ethernet::MAX_PKTLEN];
-    memset(pktbuf, 0, sizeof(pktbuf));
-
-    fd_set read_fds;
-    FD_ZERO(&read_fds);
-    FD_SET(enet->fd(), &read_fds);
-    
-    select(enet->fd()+1, &read_fds, 0, 0, &timeout);
-    while(1) {
-      memset(pktbuf, 0, sizeof(pktbuf));
-      int len = enet->read_packet_dont_block(pktbuf, sizeof(pktbuf));
-      if (len < 0){
-       perror("usrp2_basic: read_packet_dont_block");
-        return;
-      }
-      if (len == 0)
-       break;
-      
-      reply *rp = (reply *)pktbuf;
-      if (rp->op_id_reply.opcode != OP_ID_REPLY)       // ignore
-       continue;
-      
-      props p = reply_to_props(&rp->op_id_reply);
-      if (FIND_DEBUG)
-       std::cerr << "usrp2::find: response from " << p.addr << std::endl;
-      
-      if ((target_addr == "") || (target_addr == p.addr))
-       result.push_back(p);
-    }
-  }
-
-  props_vector_t
-  find(const std::string &ifc, const std::string &addr)
-  {
-    if (FIND_DEBUG) {
-      std::cerr << "usrp2::find: Searching interface " << ifc << " for "
-               << (addr == "" ? "all USRP2s" : addr)
-               << std::endl;
-    }
-    
-    props_vector_t result;
-    struct command {
-      u2_eth_packet_t  h;
-      op_generic_t     op_id;
-    };
-    
-    std::auto_ptr<ethernet> enet(new ethernet()); 
-    
-    if (!enet->open(ifc, htons(U2_CTRL_ETHERTYPE)))
-      return result;
-    
-    std::auto_ptr<pktfilter> 
pf(pktfilter::make_ethertype_inbound(U2_CTRL_ETHERTYPE, enet->mac()));
-    if (!enet->attach_pktfilter(pf.get()))
-      return result;
-    
-    static u2_mac_addr_t broadcast_mac_addr =
+#define FIND_DEBUG false
+
+#define TRANSPORT_RECV_TIMEOUT 0.01 //10ms
+#define FIND_RESPONSE_TIMEOUT 0.05 //50ms
+
+static const u2_mac_addr_t broadcast_mac_addr =
       {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
-    
-    uint8_t pktbuf[ethernet::MAX_PKTLEN];
-    memset(pktbuf, 0, sizeof(pktbuf));
-    
-    command *c = (command *)pktbuf;
-    c->h.ehdr.ethertype = htons(U2_CTRL_ETHERTYPE);
-    c->h.ehdr.dst = broadcast_mac_addr;
-    memcpy(&c->h.ehdr.src, enet->mac(), 6);
-    c->h.thdr.flags = 0;
-    c->h.thdr.seqno = 0;
-    c->h.thdr.ack = 0;
-    c->op_id.opcode = OP_ID;
-    c->op_id.len = sizeof(c->op_id);
-    int len = std::max((size_t) ethernet::MIN_PKTLEN, sizeof(command));
-    if (enet->write_packet(c, len) != len)
-      return result;
-    
-    if (FIND_DEBUG)
-      std::cerr << "usrp2::find: broadcast ID command" << std::endl;
-    
-    /*
-     * Gather all responses that occur within 50ms
-     */
-    boost::posix_time::ptime 
start(boost::posix_time::microsec_clock::universal_time());
-    boost::posix_time::ptime limit(start + 
boost::posix_time::milliseconds(50));
-    boost::posix_time::ptime now;
-
-    while (1){
-      now = boost::posix_time::microsec_clock::universal_time();
-      if (now >= limit)
-       break;
-
-      boost::posix_time::time_duration delta(limit - now);
-      struct timeval timeout = time_duration_to_timeval(delta);
-
-      read_replies(enet.get(), timeout, addr, result);
+
+namespace usrp2{
+    class find_helper{
+    private:
+        const std::string d_target_addr;
+        transport::sptr   d_ctrl_transport;
+        props_vector_t    d_result;
+
+    public:
+        typedef boost::shared_ptr<find_helper> sptr;
+
+        find_helper(const std::string &ifc, const std::string &addr): 
d_target_addr(addr){
+            d_ctrl_transport = transport::sptr(new eth_ctrl_transport(ifc, 
broadcast_mac_addr, TRANSPORT_RECV_TIMEOUT, false));
+            
d_ctrl_transport->set_callback(boost::bind(&find_helper::handle_control_packet, 
this, _1));
+        }
+
+        ~find_helper(void){/*NOP*/}
+
+        props_vector_t find(void){
+            //build the control packet
+            op_generic_t op_id;
+            op_id.opcode = OP_ID;
+            op_id.len = sizeof(op_generic_t);
+            //send the control packet
+            iovec iov;
+            iov.iov_base = &op_id;
+            iov.iov_len = sizeof(op_generic_t);
+            d_ctrl_transport->sendv(&iov, 1);
+            //allow responses to gather
+            d_ctrl_transport->start();
+            
boost::this_thread::sleep(gruel::get_new_timeout(FIND_RESPONSE_TIMEOUT));
+            d_ctrl_transport->stop();
+            return d_result;
+        }
+
+    private:
+        static props
+        reply_to_props(const op_id_reply_t *r)
+        {
+            const uint8_t *mac = (const uint8_t *)&r->addr;
+            char addr_buf[128];
+            snprintf(addr_buf, sizeof(addr_buf), 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+              
+            props p;
+            p.addr = std::string(addr_buf);  
+            p.hw_rev = ntohs(r->hw_rev);
+            memcpy(p.fpga_md5sum, r->fpga_md5sum, sizeof(p.fpga_md5sum));
+            memcpy(p.sw_md5sum, r->sw_md5sum, sizeof(p.sw_md5sum));
+            return p;
+        }
+
+        void handle_control_packet(const std::vector<sbuff::sptr> &sbs){
+            for (size_t i = 0; i < sbs.size(); i++){
+
+                //copy the packet into an reply structure
+                op_id_reply_t op_id_reply;
+                memset(&op_id_reply, 0, sizeof(op_id_reply_t));
+                memcpy(&op_id_reply, sbs[i]->buff(), 
std::min(sizeof(op_id_reply_t), sbs[i]->len()));
+
+                //inspect the reply packet and store into result
+                if (op_id_reply.opcode != OP_ID_REPLY) // ignore
+                    continue;
+                props p = reply_to_props(&op_id_reply);
+                if (FIND_DEBUG)
+                    std::cerr << "usrp2::find: response from " << p.addr << 
std::endl;
+                if ((d_target_addr == "") || (d_target_addr == p.addr))
+                    d_result.push_back(p);
+            }
+        }
+    };
+
+    props_vector_t
+    find(const std::string &ifc, const std::string &addr)
+    {
+        if (FIND_DEBUG) {
+            std::cerr << "usrp2::find: Searching interface " << ifc << " for "
+                      << (addr == "" ? "all USRP2s" : addr)
+                      << std::endl;
+        }
+        find_helper::sptr fh(new find_helper(ifc, addr));
+        return fh->find();
     }
-    return result;
-  }
-  
+
 } // namespace usrp2
 
diff --git a/usrp2/host/lib/ring.cc b/usrp2/host/lib/ring.cc
index 0eae8c1..2578e6a 100644
--- a/usrp2/host/lib/ring.cc
+++ b/usrp2/host/lib/ring.cc
@@ -42,7 +42,7 @@ namespace usrp2 {
   }
 
   bool
-  ring::enqueue(ring_data &rd)
+  ring::enqueue(const ring_data &rd)
   {
     gruel::scoped_lock l(d_mutex);
     if (full())
diff --git a/usrp2/host/lib/ring.h b/usrp2/host/lib/ring.h
index 477bd51..0be835b 100644
--- a/usrp2/host/lib/ring.h
+++ b/usrp2/host/lib/ring.h
@@ -81,7 +81,7 @@ namespace usrp2 {
 
     void wait_for_not_empty();
 
-    bool enqueue(ring_data &rd);
+    bool enqueue(const ring_data &rd);
     bool dequeue(ring_data &rd);
   };
 
diff --git a/usrp2/host/lib/transport.h b/usrp2/host/lib/transport.h
index 50eec5c..681a480 100644
--- a/usrp2/host/lib/transport.h
+++ b/usrp2/host/lib/transport.h
@@ -29,7 +29,7 @@ namespace usrp2 {
 
   class transport {
   public:
-    typedef boost::function<void(std::vector<sbuff::sptr> &)> callback_t;
+    typedef boost::function<void(const std::vector<sbuff::sptr> &)> callback_t;
     typedef boost::shared_ptr<transport> sptr;
   private:
     std::string              d_type_str;
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
index 0c7b1cc..f862eb5 100644
--- a/usrp2/host/lib/usrp2_impl.cc
+++ b/usrp2/host/lib/usrp2_impl.cc
@@ -206,7 +206,7 @@ namespace usrp2 {
   }
 
   void
-  usrp2::impl::handle_control_packet(std::vector<sbuff::sptr> &sbs)
+  usrp2::impl::handle_control_packet(const std::vector<sbuff::sptr> &sbs)
   {    
     for (size_t i = 0; i < sbs.size(); i++) {
         sbuff::sptr sb = sbs[i];
@@ -244,7 +244,7 @@ namespace usrp2 {
   }
   
   void
-  usrp2::impl::handle_data_packet(std::vector<sbuff::sptr> &sbs)
+  usrp2::impl::handle_data_packet(const std::vector<sbuff::sptr> &sbs)
   {
     if (d_dont_enqueue) return; //FIXME call done, or let the sptrs do it?
 
@@ -259,7 +259,7 @@ namespace usrp2 {
             &rd.hdr, &rd.payload, &rd.n32_bit_words_payload) //out
             or not rd.hdr.stream_id_p()
         ){
-            printf("Bad vrt header 0x%.8x, Packet len %u\n", rd.hdr.header, 
rd.sb->len());
+            printf("Bad vrt header 0x%.8x, Packet len %d\n", rd.hdr.header, 
(int)rd.sb->len());
             DEBUG_LOG("!");
             rd.sb->done(); //mark done, this sbuff is no longer needed
             continue;
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
index d74f903..7272d5e 100644
--- a/usrp2/host/lib/usrp2_impl.h
+++ b/usrp2/host/lib/usrp2_impl.h
@@ -90,8 +90,8 @@ namespace usrp2 {
     void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
     bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double 
secs=0.0);
     bool transmit_cmd(void *cmd, size_t len);
-    void handle_control_packet(std::vector<sbuff::sptr> &sbs);
-    void handle_data_packet(std::vector<sbuff::sptr> &sbs);
+    void handle_control_packet(const std::vector<sbuff::sptr> &sbs);
+    void handle_data_packet(const std::vector<sbuff::sptr> &sbs);
     bool dboard_info();
     bool reset_db();
 



reply via email to

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