This fixes the bulk of the problem. Next step is to drop data packets
while waiting for the reply.
namespace usrp2 {
pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len)
namespace usrp2 {
pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len)
- : d_rid(rid), d_mutex(), d_cond(&d_mutex), d_buffer(buffer), d_len(len)
+ : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(&d_mutex),
+ d_complete(false)
{
}
pending_reply::~pending_reply()
{
{
}
pending_reply::~pending_reply()
{
+ notify_completion(); // Needed?
- pending_reply::wait(double secs)
+ pending_reply::wait_for_completion(double secs)
- omni_mutex_lock l(d_mutex);
omni_time abs_timeout = omni_time::time(omni_time(secs));
omni_time abs_timeout = omni_time::time(omni_time(secs));
- return d_cond.timedwait(abs_timeout.d_secs, abs_timeout.d_nsecs);
+ omni_mutex_lock l(d_mutex);
+ while (!d_complete){
+ int r = d_cond.timedwait(abs_timeout.d_secs, abs_timeout.d_nsecs);
+ if (r == 0) // timed out
+ return 0;
+ }
+ return 1;
- pending_reply::signal()
+ pending_reply::notify_completion()
+ omni_mutex_lock l(d_mutex);
+ d_complete = true;
{
private:
unsigned int d_rid;
{
private:
unsigned int d_rid;
- omni_mutex d_mutex;
- omni_condition d_cond;
void *d_buffer;
size_t d_len;
void *d_buffer;
size_t d_len;
+
+ // d_mutex is used with d_cond and also protects d_complete
+ omni_mutex d_mutex;
+ omni_condition d_cond;
+ bool d_complete;
* Returns: 1 = ok, reply packet in buffer
* 0 = timeout
*/
* Returns: 1 = ok, reply packet in buffer
* 0 = timeout
*/
+ int wait_for_completion(double secs);
/*!
* Allows creating thread to resume after copying reply into buffer
*/
/*!
* Allows creating thread to resume after copying reply into buffer
*/
+ void notify_completion();
/*!
* Retrieve pending reply ID
/*!
* Retrieve pending reply ID
cmd->eop.len = sizeof(cmd->eop);
}
cmd->eop.len = sizeof(cmd->eop);
}
+
+ bool
+ usrp2::impl::transmit_cmd(void *cmd, size_t len)
+ {
+ return d_eth_buf->tx_frame(cmd, len) == eth_buffer::EB_OK;
+ }
+
- usrp2::impl::transmit_cmd(void *cmd, size_t len, pending_reply *p, double secs)
+ usrp2::impl::transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs)
- if (p)
- d_pending_replies[p->rid()] = p;
+ d_pending_replies[p->rid()] = p;
- // Transmit command
- if (d_eth_buf->tx_frame(cmd, len) != eth_buffer::EB_OK) {
+ if (!transmit_cmd(cmd, len)){
d_pending_replies[p->rid()] = 0;
return false;
}
d_pending_replies[p->rid()] = 0;
return false;
}
- int res = 1;
- if (p)
- res = p->wait(secs);
-
+ int res = p->wait_for_completion(secs);
d_pending_replies[p->rid()] = 0;
return res == 1;
}
d_pending_replies[p->rid()] = 0;
return res == 1;
}
// Copy reply into caller's buffer
memcpy(rp->buffer(), p, std::min(oplen, buflen));
// Copy reply into caller's buffer
memcpy(rp->buffer(), p, std::min(oplen, buflen));
+ rp->notify_completion();
d_pending_replies[rid] = 0;
return data_handler::RELEASE;
}
d_pending_replies[rid] = 0;
return data_handler::RELEASE;
}
cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.decim = htonl(decimation_factor);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.decim = htonl(decimation_factor);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
bool success = false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
bool success = false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- success = transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+ success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
success = success && (ntohx(reply.ok) == 1);
if (success)
d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
success = success && (ntohx(reply.ok) == 1);
if (success)
d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
+ //fprintf(stderr, "usrp2::start_rx_streaming: success = %d\n", success);
bool success = false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
bool success = false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- success = transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+ success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, 10 * DEF_CMD_TIMEOUT);
success = success && (ntohx(reply.ok) == 1);
d_channel_rings[channel].reset();
success = success && (ntohx(reply.ok) == 1);
d_channel_rings[channel].reset();
+ //fprintf(stderr, "usrp2::stop_rx_streaming: success = %d\n", success);
cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.interp = htonl(interpolation_factor);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.interp = htonl(interpolation_factor);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
return ntohx(reply.ok) == 1;
return false;
return ntohx(reply.ok) == 1;
return false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
return false;
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
return ntohx(reply.ok) == 1;
return false;
return ntohx(reply.ok) == 1;
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
return ntohx(reply.ok) == 1;
return false;
return ntohx(reply.ok) == 1;
reply = (op_generic_t *)malloc(rlen+bytes);
pending_reply p(cmd.op.rid, reply, rlen+bytes);
reply = (op_generic_t *)malloc(rlen+bytes);
pending_reply p(cmd.op.rid, reply, rlen+bytes);
- if (transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
+ if (transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
uint32_t nwords = (reply->len-rlen)/sizeof(uint32_t);
uint32_t *data = (uint32_t *)(reply+rlen/wlen);
for (unsigned int i = 0; i < nwords; i++)
uint32_t nwords = (reply->len-rlen)/sizeof(uint32_t);
uint32_t *data = (uint32_t *)(reply+rlen/wlen);
for (unsigned int i = 0; i < nwords; i++)
bool ok = false;
op_generic_t reply;
pending_reply p(cmd->op.rid, &reply, sizeof(reply));
bool ok = false;
op_generic_t reply;
pending_reply p(cmd->op.rid, &reply, sizeof(reply));
- if (transmit_cmd(cmd, l, &p, DEF_CMD_TIMEOUT))
+ if (transmit_cmd_and_wait(cmd, l, &p, DEF_CMD_TIMEOUT))
ok = (ntohx(reply.ok) == 1);
free(cmd);
ok = (ntohx(reply.ok) == 1);
free(cmd);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
cmd.eop.len = sizeof(cmd.eop);
pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
return false;
bool success = (ntohx(reply.ok) == 1);
return false;
bool success = (ntohx(reply.ok) == 1);
void stop_bg();
void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
void stop_bg();
void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
- bool transmit_cmd(void *cmd, size_t len, pending_reply *p, double secs=0.0);
+ 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);
virtual data_handler::result operator()(const void *base, size_t len);
data_handler::result handle_control_packet(const void *base, size_t len);
data_handler::result handle_data_packet(const void *base, size_t len);
virtual data_handler::result operator()(const void *base, size_t len);
data_handler::result handle_control_packet(const void *base, size_t len);
data_handler::result handle_data_packet(const void *base, size_t len);