]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/ipdbg-la/protocol.c
ipdbg-la: working on windows
[libsigrok.git] / src / hardware / ipdbg-la / protocol.c
index edebe61cf9be77722c7c4ad8f3010c231dd12458..ac36b060839ab61c477506bff5e3fa5668060f82 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,15 @@ 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 +159,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,7 +175,7 @@ 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;
@@ -200,7 +202,7 @@ SR_PRIV int ipdbg_la_tcp_receive(struct ipdbg_la_tcp *tcp,
 
        if (data_available(tcp)) {
                while (received < 1) {
-                       int len = recv(tcp->socket, buf, 1, 0);
+                       int len = recv(tcp->socket, (char *)buf, 1, 0);
 
                        if (len < 0) {
                                sr_err("Receive error: %s", g_strerror(errno));
@@ -357,6 +359,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 +389,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 +412,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 +424,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 +436,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 +448,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 +460,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 +473,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 +525,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 +534,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 +565,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;