[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();
- [Commit-gnuradio] [gnuradio] 50/148: make the testbench work in this environment, without the crossclock settings bus, (continued)
- [Commit-gnuradio] [gnuradio] 50/148: make the testbench work in this environment, without the crossclock settings bus, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 26/148: moved regs around for vita49, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 19/148: VITA49 rx (and tx skeleton) copied over from quad radio, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 43/148: minor tweak to transport loop and debug printf for vrt, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 44/148: Removed temporary u2_eth_packet_only_t. Removed the fixed header portion from the u2_eth_packet_t. Removed places in code where control uses the fixed header (always unused 0 for word, and -1 for timestamp). Flagged the fixed header stuff for removal (once we get vrt tx)., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 25/148: cleanup, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 42/148: Created a ring data structure held by the ring. It holds an sbuff and its parsed vrt data (header, payload, and len). The impl data handler parses the packets and enqueues them., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 48/148: Added interrupt call from transport::stop so the recv or callback will throw at interruption points. This fixes the issue where the app would hang in the stop method when exiting (we were hanging here: d_data_pending_cond.wait(l), but now wait throws() and we exit)., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 54/148: flag packets which arrive way too early so the device doesn't sit there forever., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 38/148: rx working with vrt header, git, 2016/08/14
- [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.,
git <=
- [Commit-gnuradio] [gnuradio] 49/148: Added read_packet with timeout method to ethernet. Now the control recv can timeout and immediately recv., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 21/148: put 64 bit timer for vita49 on the settings bus, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 47/148: Handled the case of short packets in eth data transport by using padding., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 70/148: changed debug pins to see incoming data, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 51/148: progress on vita_tx. it compiles now, need to work on vita_tx_control., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 46/148: Created and used a typedef for a vector of sbuffs. Changed the return type for the transport sendv to bool. Not all transports can return the number of bytes sent, and we only care if the transport succeeded or not. This fixes an issue of the usrp2 impl freezing on close after tx, because the return value from sednv was improperly handled., git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 66/148: Merge branch 'vita_rx' of http://gnuradio.org/git/matt into wip/usrp2, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 79/148: cleaned up the main ibs state machine, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 71/148: Merge branch 'vita_rx' of gnuradio.org:matt into vita_rx, git, 2016/08/14
- [Commit-gnuradio] [gnuradio] 53/148: very basic packet sending works, git, 2016/08/14