xvc_client: block until full reply received, fixes errors on a slow network
ll_write() can request more than 1.5K of data, but recv() call will return right away as soon as one packet is received. This causes large transfers to break as not enough data is received. Fixed by adding rx_exact flag and enabled it for ll_write() Tested with Zynq7010 on a slow WiFi. Before the patch all uploads were silently failing with no error in the log. Signed-off-by: Vadzim Dambrouski <pftbest@gmail.com>
This commit is contained in:
parent
77db4dae64
commit
4af13b96ab
|
|
@ -261,9 +261,26 @@ int sendall(int sock, const void* raw, size_t cnt, int flags)
|
||||||
return cnt; // success
|
return cnt; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ssize_t recvall(int sock, void* raw, size_t cnt, int flags)
|
||||||
|
{
|
||||||
|
char *buf = (char*)raw;
|
||||||
|
size_t remaining = cnt;
|
||||||
|
while (remaining) {
|
||||||
|
ssize_t ret = recv(sock, buf, remaining, flags);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (ret == 0) // peer closed the connection mid-reply
|
||||||
|
break;
|
||||||
|
buf += ret;
|
||||||
|
remaining -= ret;
|
||||||
|
}
|
||||||
|
return cnt - remaining;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t XVC_client::xfer_pkt(const std::string &instr,
|
ssize_t XVC_client::xfer_pkt(const std::string &instr,
|
||||||
const uint8_t *tx, uint32_t tx_size,
|
const uint8_t *tx, uint32_t tx_size,
|
||||||
uint8_t *rx, uint32_t rx_size)
|
uint8_t *rx, uint32_t rx_size, bool rx_exact)
|
||||||
{
|
{
|
||||||
ssize_t len = tx_size;
|
ssize_t len = tx_size;
|
||||||
std::vector<uint8_t> buffer(instr.size() + ((tx) ? tx_size : 0));
|
std::vector<uint8_t> buffer(instr.size() + ((tx) ? tx_size : 0));
|
||||||
|
|
@ -277,9 +294,14 @@ ssize_t XVC_client::xfer_pkt(const std::string &instr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx) {
|
if (rx) {
|
||||||
|
if (rx_exact) {
|
||||||
|
len = recvall(_sock, rx, rx_size, 0);
|
||||||
|
} else {
|
||||||
len = recv(_sock, rx, rx_size, 0);
|
len = recv(_sock, rx, rx_size, 0);
|
||||||
|
}
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
printError("Receive error");
|
printError("Receive error");
|
||||||
|
return len;
|
||||||
} else if (len == 0) {
|
} else if (len == 0) {
|
||||||
fprintf(stderr, "Client orderly shut down the connection.\n");
|
fprintf(stderr, "Client orderly shut down the connection.\n");
|
||||||
}
|
}
|
||||||
|
|
@ -312,7 +334,7 @@ bool XVC_client::ll_write(uint8_t *tdo)
|
||||||
memcpy(_xfer_buf + 4 + numbytes, _tditdo, numbytes);
|
memcpy(_xfer_buf + 4 + numbytes, _tditdo, numbytes);
|
||||||
|
|
||||||
if ((ret = xfer_pkt("shift:\0", _xfer_buf, (2 * numbytes) + 4,
|
if ((ret = xfer_pkt("shift:\0", _xfer_buf, (2 * numbytes) + 4,
|
||||||
_tditdo, numbytes)) < 0)
|
_tditdo, numbytes, true)) < 0)
|
||||||
return false;
|
return false;
|
||||||
_num_bits = 0; // clear counter
|
_num_bits = 0; // clear counter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,11 +95,12 @@ class XVC_client: public JtagInterface {
|
||||||
* \param[in] tx_size: tx size (in Byte)
|
* \param[in] tx_size: tx size (in Byte)
|
||||||
* \param[in] rx: server answer buffer (may be NULL)
|
* \param[in] rx: server answer buffer (may be NULL)
|
||||||
* \param[in] rx_size: rx size (in Byte) or (0 when unused)
|
* \param[in] rx_size: rx size (in Byte) or (0 when unused)
|
||||||
|
* \param[in] rx_exact: block until exactly rx_size bytes received
|
||||||
* \return -1 when error, 0 when disconnected or tx_size/rx_size
|
* \return -1 when error, 0 when disconnected or tx_size/rx_size
|
||||||
*/
|
*/
|
||||||
ssize_t xfer_pkt(const std::string &instr,
|
ssize_t xfer_pkt(const std::string &instr,
|
||||||
const uint8_t *tx, uint32_t tx_size,
|
const uint8_t *tx, uint32_t tx_size,
|
||||||
uint8_t *rx, uint32_t rx_size);
|
uint8_t *rx, uint32_t rx_size, bool rx_exact = false);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief lowlevel write: EMU_CMD_HW_JTAGx implementation
|
* \brief lowlevel write: EMU_CMD_HW_JTAGx implementation
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue