diff --git a/src/xvc_client.cpp b/src/xvc_client.cpp index 8d6f38d..0665e4f 100644 --- a/src/xvc_client.cpp +++ b/src/xvc_client.cpp @@ -261,9 +261,26 @@ int sendall(int sock, const void* raw, size_t cnt, int flags) 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, 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; std::vector buffer(instr.size() + ((tx) ? tx_size : 0)); @@ -277,9 +294,14 @@ ssize_t XVC_client::xfer_pkt(const std::string &instr, } if (rx) { - len = recv(_sock, rx, rx_size, 0); + if (rx_exact) { + len = recvall(_sock, rx, rx_size, 0); + } else { + len = recv(_sock, rx, rx_size, 0); + } if (len < 0) { printError("Receive error"); + return len; } else if (len == 0) { 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); if ((ret = xfer_pkt("shift:\0", _xfer_buf, (2 * numbytes) + 4, - _tditdo, numbytes)) < 0) + _tditdo, numbytes, true)) < 0) return false; _num_bits = 0; // clear counter diff --git a/src/xvc_client.hpp b/src/xvc_client.hpp index 9bd7169..bbb0789 100644 --- a/src/xvc_client.hpp +++ b/src/xvc_client.hpp @@ -95,11 +95,12 @@ class XVC_client: public JtagInterface { * \param[in] tx_size: tx size (in Byte) * \param[in] rx: server answer buffer (may be NULL) * \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 */ ssize_t xfer_pkt(const std::string &instr, 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