summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-02-12 16:40:07 -0800
committerJosh Blum <josh@joshknows.com>2012-02-20 10:51:36 -0800
commitb1f34b4fd06bd54bcf52860e6d1fe63ad30f2105 (patch)
treedcdab3ea41b7ba06bcb56116166e88a486a06b72
parent0df49b75024dbf205effa5bd8530173423a4d7a8 (diff)
downloaduhd-b1f34b4fd06bd54bcf52860e6d1fe63ad30f2105.tar.gz
uhd-b1f34b4fd06bd54bcf52860e6d1fe63ad30f2105.tar.bz2
uhd-b1f34b4fd06bd54bcf52860e6d1fe63ad30f2105.zip
usrp2: added retry logic to control packets
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index eeba6756e..a56d292c2 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -39,6 +39,17 @@ using namespace uhd::usrp;
using namespace uhd::transport;
static const double CTRL_RECV_TIMEOUT = 1.0;
+static const size_t CTRL_RECV_RETRIES = 3;
+
+//custom timeout error for retry logic to catch/retry
+struct timeout_error : uhd::runtime_error
+{
+ timeout_error(const std::string &what):
+ uhd::runtime_error(what)
+ {
+ //NOP
+ }
+};
static const boost::uint32_t MIN_PROTO_COMPAT_SPI = 7;
static const boost::uint32_t MIN_PROTO_COMPAT_I2C = 7;
@@ -264,6 +275,25 @@ public:
){
boost::mutex::scoped_lock lock(_ctrl_mutex);
+ for (size_t i = 0; i < CTRL_RECV_RETRIES; i++){
+ try{
+ return ctrl_send_and_recv_internal(out_data, lo, hi, CTRL_RECV_TIMEOUT/CTRL_RECV_RETRIES);
+ }
+ catch(const timeout_error &e){
+ UHD_MSG(error)
+ << "Control packet attempt " << i
+ << ", sequence number " << _ctrl_seq_num
+ << ":\n" << e.what() << std::endl;
+ }
+ }
+ throw uhd::runtime_error("link dead: timeout waiting for control packet ACK");
+ }
+
+ usrp2_ctrl_data_t ctrl_send_and_recv_internal(
+ const usrp2_ctrl_data_t &out_data,
+ boost::uint32_t lo, boost::uint32_t hi,
+ const double timeout
+ ){
//fill in the seq number and send
usrp2_ctrl_data_t out_copy = out_data;
out_copy.proto_ver = htonl(_protocol_compat);
@@ -274,7 +304,7 @@ public:
boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv
const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);
while(true){
- size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CTRL_RECV_TIMEOUT);
+ size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), timeout);
boost::uint32_t compat = ntohl(ctrl_data_in->proto_ver);
if(len >= sizeof(boost::uint32_t) and (hi < compat or lo > compat)){
throw uhd::runtime_error(str(boost::format(
@@ -290,7 +320,7 @@ public:
if (len == 0) break; //timeout
//didnt get seq or bad packet, continue looking...
}
- throw uhd::runtime_error("no control response");
+ throw timeout_error("no control response, possible packet loss");
}
rev_type get_rev(void){