]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/ipdbg-la/protocol.c
ipdbg-la: Minor cosmetic and comment fixes.
[libsigrok.git] / src / hardware / ipdbg-la / protocol.c
index edebe61cf9be77722c7c4ad8f3010c231dd12458..fc27f62df69c3cc190dd938c80ed98c7fe77c6f2 100644 (file)
 #define _WIN32_WINNT 0x0501
 #include <winsock2.h>
 #include <ws2tcpip.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-
-#ifndef _WIN32
+#else
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <sys/ioctl.h>
 #endif
-
+#include <string.h>
+#include <unistd.h>
 #include <errno.h>
 #include "protocol.h"
 
-#include <sys/ioctl.h>
-
 #define BUFFER_SIZE 4
 
 /* Top-level command opcodes */
 /* LA subfunction command opcodes */
 #define CMD_LA_DELAY               0x1F
 
-SR_PRIV gboolean data_available(struct ipdbg_la_tcp *tcp)
+static gboolean data_available(struct ipdbg_la_tcp *tcp)
 {
-#ifdef __WIN32__
-       ioctlsocket(tcp->socket, FIONREAD, &bytes_available);
+#ifdef _WIN32
+       u_long bytes_available;
+       if (ioctlsocket(tcp->socket, FIONREAD, &bytes_available) != 0) {
 #else
-       int status;
-
-       if (ioctl(tcp->socket, FIONREAD, &status) < 0) {        // TIOCMGET
+       int bytes_available;
+       if (ioctl(tcp->socket, FIONREAD, &bytes_available) < 0) { /* TIOCMGET */
+#endif
                sr_err("FIONREAD failed: %s\n", g_strerror(errno));
                return FALSE;
        }
-
-       return (status < 1) ? FALSE : TRUE;
-#endif  // __WIN32__
+       return (bytes_available > 0);
 }
 
 SR_PRIV struct ipdbg_la_tcp *ipdbg_la_tcp_new(void)
@@ -148,6 +142,14 @@ SR_PRIV int ipdbg_la_tcp_close(struct ipdbg_la_tcp *tcp)
 {
        int ret = SR_OK;
 
+#ifdef _WIN32
+       if (shutdown(tcp->socket, SD_SEND) != SOCKET_ERROR) {
+               char recvbuf[16];
+               int recvbuflen = 16;
+               /* Receive until the peer closes the connection. */
+               while (recv(tcp->socket, recvbuf, recvbuflen, 0) > 0);
+       }
+#endif
        if (close(tcp->socket) < 0)
                ret = SR_ERR;
 
@@ -156,11 +158,10 @@ SR_PRIV int ipdbg_la_tcp_close(struct ipdbg_la_tcp *tcp)
        return ret;
 }
 
-SR_PRIV int ipdbg_la_tcp_send(struct ipdbg_la_tcp *tcp,
-       const uint8_t *buf, size_t len)
+static int tcp_send(struct ipdbg_la_tcp *tcp, const uint8_t *buf, size_t len)
 {
        int out;
-       out = send(tcp->socket, buf, len, 0);
+       out = send(tcp->socket, (const char *)buf, len, 0);
 
        if (out < 0) {
                sr_err("Send error: %s", g_strerror(errno));
@@ -173,20 +174,22 @@ SR_PRIV int ipdbg_la_tcp_send(struct ipdbg_la_tcp *tcp,
        return SR_OK;
 }
 
-SR_PRIV int ipdbg_la_tcp_receive_blocking(struct ipdbg_la_tcp *tcp,
+static int tcp_receive_blocking(struct ipdbg_la_tcp *tcp,
        uint8_t *buf, int bufsize)
 {
        int received = 0;
        int error_count = 0;
 
-       /* Timeout after 500ms of not receiving data */
-       while ((received < bufsize) && (error_count < 500)) {
-               if (ipdbg_la_tcp_receive(tcp, buf) > 0) {
-                       buf++;
-                       received++;
+       /* Timeout after 2s of not receiving data. */
+       /* Increase timeout in case lab is not just beside the office. */
+       while ((received < bufsize) && (error_count < 2000)) {
+               int recd = ipdbg_la_tcp_receive(tcp, buf, bufsize - received);
+               if (recd > 0) {
+                       buf += recd;
+                       received += recd;
                } else {
                        error_count++;
-                       g_usleep(1000);  /* Sleep for 1ms */
+                       g_usleep(1000);
                }
        }
 
@@ -194,24 +197,16 @@ SR_PRIV int ipdbg_la_tcp_receive_blocking(struct ipdbg_la_tcp *tcp,
 }
 
 SR_PRIV int ipdbg_la_tcp_receive(struct ipdbg_la_tcp *tcp,
-       uint8_t *buf)
+       uint8_t *buf, size_t bufsize)
 {
        int received = 0;
-
-       if (data_available(tcp)) {
-               while (received < 1) {
-                       int len = recv(tcp->socket, buf, 1, 0);
-
-                       if (len < 0) {
-                               sr_err("Receive error: %s", g_strerror(errno));
-                               return SR_ERR;
-                       } else
-                               received += len;
-               }
-
-               return received;
-       } else
+       if (data_available(tcp))
+               received = recv(tcp->socket, (char *)buf, bufsize, 0);
+       if (received < 0) {
+               sr_err("Receive error: %s", g_strerror(errno));
                return -1;
+       } else
+               return received;
 }
 
 SR_PRIV int ipdbg_la_convert_trigger(const struct sr_dev_inst *sdi)
@@ -314,14 +309,22 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
 
        if (devc->num_transfers <
                (devc->limit_samples_max * devc->data_width_bytes)) {
-               uint8_t byte;
-
-               if (ipdbg_la_tcp_receive(tcp, &byte) == 1) {
-                       if (devc->num_transfers <
-                               (devc->limit_samples * devc->data_width_bytes))
-                               devc->raw_sample_buf[devc->num_transfers] = byte;
-
-                       devc->num_transfers++;
+               const size_t bufsize = 1024;
+               uint8_t buffer[bufsize];
+
+               const int recd = ipdbg_la_tcp_receive(tcp, buffer, bufsize);
+               if ( recd > 0) {
+                       int num_move = (((devc->num_transfers + recd) <=
+                                                        (devc->limit_samples * devc->data_width_bytes))
+                       ?
+                               recd
+                       :
+                               (int)((devc->limit_samples * devc->data_width_bytes) -
+                                               devc->num_transfers));
+                       if ( num_move > 0 )
+                               memcpy(&(devc->raw_sample_buf[devc->num_transfers]),
+                                               buffer, num_move);
+                       devc->num_transfers += recd;
                }
        } else {
                if (devc->delay_value > 0) {
@@ -357,6 +360,29 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
        return TRUE;
 }
 
+static int send_escaping(struct ipdbg_la_tcp *tcp, uint8_t *data_to_send,
+       uint32_t length)
+{
+       uint8_t escape = CMD_ESCAPE;
+
+       while (length--) {
+               uint8_t payload = *data_to_send++;
+
+               if (payload == CMD_RESET)
+                       if (tcp_send(tcp, &escape, 1) != SR_OK)
+                               sr_warn("Couldn't send escape");
+
+               if (payload == CMD_ESCAPE)
+                       if (tcp_send(tcp, &escape, 1) != SR_OK)
+                               sr_warn("Couldn't send escape");
+
+               if (tcp_send(tcp, &payload, 1) != SR_OK)
+                       sr_warn("Couldn't send data");
+       }
+
+       return SR_OK;
+}
+
 SR_PRIV int ipdbg_la_send_delay(struct dev_context *devc,
        struct ipdbg_la_tcp *tcp)
 {
@@ -364,9 +390,9 @@ SR_PRIV int ipdbg_la_send_delay(struct dev_context *devc,
 
        uint8_t buf;
        buf = CMD_CFG_LA;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_LA_DELAY;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        uint8_t delay_buf[4] = { devc->delay_value & 0x000000ff,
                (devc->delay_value >> 8) & 0x000000ff,
@@ -387,11 +413,11 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
 
        /* Mask */
        buf = CMD_CFG_TRIGGER;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASKS;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASK;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
@@ -399,11 +425,11 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
 
        /* Value */
        buf = CMD_CFG_TRIGGER;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASKS;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_VALUE;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
@@ -411,11 +437,11 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
 
        /* Mask_last */
        buf = CMD_CFG_TRIGGER;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASKS_LAST;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASK_LAST;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
@@ -423,11 +449,11 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
 
        /* Value_last */
        buf = CMD_CFG_TRIGGER;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_MASKS_LAST;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_VALUE_LAST;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
@@ -435,11 +461,11 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
 
        /* Edge_mask */
        buf = CMD_CFG_TRIGGER;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_SELECT_EDGE_MASK;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
        buf = CMD_TRIG_SET_EDGE_MASK;
-       ipdbg_la_tcp_send(tcp, &buf, 1);
+       tcp_send(tcp, &buf, 1);
 
        for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
@@ -448,39 +474,16 @@ SR_PRIV int ipdbg_la_send_trigger(struct dev_context *devc,
        return SR_OK;
 }
 
-SR_PRIV int send_escaping(struct ipdbg_la_tcp *tcp, uint8_t *data_to_send,
-       uint32_t length)
-{
-       uint8_t escape = CMD_ESCAPE;
-
-       while (length--) {
-               uint8_t payload = *data_to_send++;
-
-               if (payload == CMD_RESET)
-                       if (ipdbg_la_tcp_send(tcp, &escape, 1) != SR_OK)
-                               sr_warn("Couldn't send escape");
-
-               if (payload == CMD_ESCAPE)
-                       if (ipdbg_la_tcp_send(tcp, &escape, 1) != SR_OK)
-                               sr_warn("Couldn't send escape");
-
-               if (ipdbg_la_tcp_send(tcp, &payload, 1) != SR_OK)
-                       sr_warn("Couldn't send data");
-       }
-
-       return SR_OK;
-}
-
 SR_PRIV void ipdbg_la_get_addrwidth_and_datawidth(
        struct ipdbg_la_tcp *tcp, struct dev_context *devc)
 {
        uint8_t buf[8];
        uint8_t read_cmd = CMD_GET_BUS_WIDTHS;
 
-       if (ipdbg_la_tcp_send(tcp, &read_cmd, 1) != SR_OK)
+       if (tcp_send(tcp, &read_cmd, 1) != SR_OK)
                sr_warn("Can't send read command");
 
-       if (ipdbg_la_tcp_receive_blocking(tcp, buf, 8) != 8)
+       if (tcp_receive_blocking(tcp, buf, 8) != 8)
                sr_warn("Can't get address and data width from device");
 
        devc->data_width = buf[0] & 0x000000FF;
@@ -523,7 +526,7 @@ SR_PRIV struct dev_context *ipdbg_la_dev_new(void)
 SR_PRIV int ipdbg_la_send_reset(struct ipdbg_la_tcp *tcp)
 {
        uint8_t buf = CMD_RESET;
-       if (ipdbg_la_tcp_send(tcp, &buf, 1) != SR_OK)
+       if (tcp_send(tcp, &buf, 1) != SR_OK)
                sr_warn("Couldn't send reset");
 
        return SR_OK;
@@ -532,11 +535,11 @@ SR_PRIV int ipdbg_la_send_reset(struct ipdbg_la_tcp *tcp)
 SR_PRIV int ipdbg_la_request_id(struct ipdbg_la_tcp *tcp)
 {
        uint8_t buf = CMD_GET_LA_ID;
-       if (ipdbg_la_tcp_send(tcp, &buf, 1) != SR_OK)
+       if (tcp_send(tcp, &buf, 1) != SR_OK)
                sr_warn("Couldn't send ID request");
 
        char id[4];
-       if (ipdbg_la_tcp_receive_blocking(tcp, (uint8_t*)id, 4) != 4) {
+       if (tcp_receive_blocking(tcp, (uint8_t *)id, 4) != 4) {
                sr_err("Couldn't read device ID");
                return SR_ERR;
        }
@@ -563,7 +566,7 @@ SR_PRIV int ipdbg_la_send_start(struct ipdbg_la_tcp *tcp)
 {
        uint8_t buf = CMD_START;
 
-       if (ipdbg_la_tcp_send(tcp, &buf, 1) != SR_OK)
+       if (tcp_send(tcp, &buf, 1) != SR_OK)
                sr_warn("Couldn't send start");
 
        return SR_OK;