beaglelogic: Add beaglelogic_tcp_drain function

The function drains off all the remaining data in the receive socket
and is triggered before starting a capture and after a capture is
completed. In the absence of this function, there is a possibility of
data corruption and also the NodeJS TCP server throws an error if the
buffer is not completely read out before the socket is closed.

Signed-off-by: Kumar Abhishek <abhishek@theembeddedkitchen.net>
This commit is contained in:
Kumar Abhishek 2017-09-23 11:09:14 +05:30 committed by Uwe Hermann
parent 9b2b3ef93e
commit f7d7ee82dd
4 changed files with 35 additions and 1 deletions

View File

@ -358,9 +358,11 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi)
/* Execute a stop on BeagleLogic */ /* Execute a stop on BeagleLogic */
devc->beaglelogic->stop(devc); devc->beaglelogic->stop(devc);
/* lseek to offset 0, flushes the cache */ /* Flush the cache */
if (devc->beaglelogic == &beaglelogic_native_ops) if (devc->beaglelogic == &beaglelogic_native_ops)
lseek(devc->fd, 0, SEEK_SET); lseek(devc->fd, 0, SEEK_SET);
else
beaglelogic_tcp_drain(devc);
/* Remove session source and send EOT packet */ /* Remove session source and send EOT packet */
sr_session_source_remove_pollfd(sdi->session, &devc->pollfd); sr_session_source_remove_pollfd(sdi->session, &devc->pollfd);

View File

@ -127,5 +127,6 @@ SR_PRIV extern const struct beaglelogic_ops beaglelogic_native_ops;
SR_PRIV extern const struct beaglelogic_ops beaglelogic_tcp_ops; SR_PRIV extern const struct beaglelogic_ops beaglelogic_tcp_ops;
SR_PRIV int beaglelogic_tcp_detect(struct dev_context *devc); SR_PRIV int beaglelogic_tcp_detect(struct dev_context *devc);
SR_PRIV int beaglelogic_tcp_drain(struct dev_context *devc);
#endif #endif

View File

@ -132,6 +132,32 @@ static int beaglelogic_tcp_read_data(struct dev_context *devc, char *buf,
return len; return len;
} }
SR_PRIV int beaglelogic_tcp_drain(struct dev_context *devc) {
char *buf = g_malloc(1024);
fd_set rset;
int ret, len = 0;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(devc->socket, &rset);
/* 25ms timeout */
tv.tv_sec = 0;
tv.tv_usec = 25 * 1000;
do {
ret = select(devc->socket + 1, &rset, NULL, NULL, &tv);
if (ret > 0) {
len += beaglelogic_tcp_read_data(devc, buf, 1024);
}
} while (ret > 0);
sr_spew("Drained %d bytes of data.", len);
g_free(buf);
return SR_OK;
}
static int beaglelogic_tcp_get_string(struct dev_context *devc, const char *cmd, static int beaglelogic_tcp_get_string(struct dev_context *devc, const char *cmd,
char **tcp_resp) { char **tcp_resp) {
GString *response = g_string_sized_new(1024); GString *response = g_string_sized_new(1024);
@ -314,6 +340,7 @@ static int beaglelogic_get_lasterror(struct dev_context *devc) {
} }
static int beaglelogic_start(struct dev_context *devc) { static int beaglelogic_start(struct dev_context *devc) {
beaglelogic_tcp_drain(devc);
return beaglelogic_tcp_send_cmd(devc, "get"); return beaglelogic_tcp_send_cmd(devc, "get");
} }

View File

@ -194,6 +194,10 @@ SR_PRIV int beaglelogic_tcp_receive_data(int fd, int revents, void *cb_data)
/* Send EOA Packet, stop polling */ /* Send EOA Packet, stop polling */
std_session_send_df_end(sdi); std_session_send_df_end(sdi);
devc->beaglelogic->stop(devc); devc->beaglelogic->stop(devc);
/* Drain the receive buffer */
beaglelogic_tcp_drain(devc);
sr_session_source_remove_pollfd(sdi->session, &devc->pollfd); sr_session_source_remove_pollfd(sdi->session, &devc->pollfd);
} }