]> 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 d02ec73720c8150c553c368513bce41262af4ef8..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 int 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
-               sr_err("FIONREAD failed: %s\n", strerror(errno));
-               return 0;
+       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) ? 0 : 1;
-#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, (char*)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));
@@ -228,7 +230,7 @@ SR_PRIV int ipdbg_la_convert_trigger(const struct sr_dev_inst *sdi)
        devc->num_transfers = 0;
        devc->raw_sample_buf = NULL;
 
-       for (uint64_t i = 0; i < devc->DATA_WIDTH_BYTES; i++) {
+       for (uint64_t i = 0; i < devc->data_width_bytes; i++) {
                devc->trigger_mask[i] = 0;
                devc->trigger_value[i] = 0;
                devc->trigger_mask_last[i] = 0;
@@ -292,7 +294,7 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
        (void)fd;
        (void)revents;
 
-       sdi = (const struct sr_dev_inst *)cb_data;
+       sdi = cb_data;
        if (!sdi)
                return FALSE;
 
@@ -305,7 +307,7 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
 
        if (!devc->raw_sample_buf) {
                devc->raw_sample_buf =
-                       g_try_malloc(devc->limit_samples * devc->DATA_WIDTH_BYTES);
+                       g_try_malloc(devc->limit_samples * devc->data_width_bytes);
                if (!devc->raw_sample_buf) {
                        sr_err("Sample buffer malloc failed.");
                        return FALSE;
@@ -313,12 +315,12 @@ 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)) {
+               (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->limit_samples * devc->data_width_bytes))
                                devc->raw_sample_buf[devc->num_transfers] = byte;
 
                        devc->num_transfers++;
@@ -328,8 +330,8 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
                        /* There are pre-trigger samples, send those first. */
                        packet.type = SR_DF_LOGIC;
                        packet.payload = &logic;
-                       logic.length = devc->delay_value * devc->DATA_WIDTH_BYTES;
-                       logic.unitsize = devc->DATA_WIDTH_BYTES;
+                       logic.length = devc->delay_value * devc->data_width_bytes;
+                       logic.unitsize = devc->data_width_bytes;
                        logic.data = devc->raw_sample_buf;
                        sr_session_send(cb_data, &packet);
                }
@@ -342,10 +344,10 @@ SR_PRIV int ipdbg_la_receive_data(int fd, int revents, void *cb_data)
                packet.type = SR_DF_LOGIC;
                packet.payload = &logic;
                logic.length = (devc->limit_samples - devc->delay_value) *
-                       devc->DATA_WIDTH_BYTES;
-               logic.unitsize = devc->DATA_WIDTH_BYTES;
+                       devc->data_width_bytes;
+               logic.unitsize = devc->data_width_bytes;
                logic.data = devc->raw_sample_buf +
-                       (devc->delay_value * devc->DATA_WIDTH_BYTES);
+                       (devc->delay_value * devc->data_width_bytes);
                sr_session_send(cb_data, &packet);
 
                g_free(devc->raw_sample_buf);
@@ -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,
@@ -374,8 +399,8 @@ SR_PRIV int ipdbg_la_send_delay(struct dev_context *devc,
                (devc->delay_value >> 24) & 0x000000ff
        };
 
-       for (uint64_t i = 0; i < devc->ADDR_WIDTH_BYTES; i++)
-               send_escaping(tcp, &(delay_buf[devc->ADDR_WIDTH_BYTES - 1 - i]), 1);
+       for (uint64_t i = 0; i < devc->addr_width_bytes; i++)
+               send_escaping(tcp, &(delay_buf[devc->addr_width_bytes - 1 - i]), 1);
 
        return SR_OK;
 }
@@ -387,86 +412,63 @@ 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++)
+       for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
-                       devc->trigger_mask + devc->DATA_WIDTH_BYTES - 1 - i, 1);
+                       devc->trigger_mask + devc->data_width_bytes - 1 - i, 1);
 
        /* 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++)
+       for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
-                       devc->trigger_value + devc->DATA_WIDTH_BYTES - 1 - i, 1);
+                       devc->trigger_value + devc->data_width_bytes - 1 - i, 1);
 
        /* 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++)
+       for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
-                       devc->trigger_mask_last + devc->DATA_WIDTH_BYTES - 1 - i, 1);
+                       devc->trigger_mask_last + devc->data_width_bytes - 1 - i, 1);
 
        /* 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++)
+       for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
-                       devc->trigger_value_last + devc->DATA_WIDTH_BYTES - 1 - i, 1);
+                       devc->trigger_value_last + devc->data_width_bytes - 1 - i, 1);
 
        /* 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++)
+       for (size_t i = 0; i < devc->data_width_bytes; i++)
                send_escaping(tcp,
-                       devc->trigger_edge_mask + devc->DATA_WIDTH_BYTES - 1 - i, 1);
-
-       return SR_OK;
-}
-
-SR_PRIV int send_escaping(struct ipdbg_la_tcp *tcp, uint8_t *dataToSend,
-       uint32_t length)
-{
-       uint8_t escape = CMD_ESCAPE;
-
-       while (length--) {
-               uint8_t payload = *dataToSend++;
-
-               if (payload == (uint8_t) CMD_RESET)
-                       if (ipdbg_la_tcp_send(tcp, &escape, 1) != SR_OK)
-                               sr_warn("Couldn't send escape");
-
-               if (payload == (uint8_t) 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");
-       }
+                       devc->trigger_edge_mask + devc->data_width_bytes - 1 - i, 1);
 
        return SR_OK;
 }
@@ -477,37 +479,37 @@ SR_PRIV void ipdbg_la_get_addrwidth_and_datawidth(
        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;
-       devc->DATA_WIDTH |= (buf[1] << 8) & 0x0000FF00;
-       devc->DATA_WIDTH |= (buf[2] << 16) & 0x00FF0000;
-       devc->DATA_WIDTH |= (buf[3] << 24) & 0xFF000000;
+       devc->data_width = buf[0] & 0x000000FF;
+       devc->data_width |= (buf[1] << 8) & 0x0000FF00;
+       devc->data_width |= (buf[2] << 16) & 0x00FF0000;
+       devc->data_width |= (buf[3] << 24) & 0xFF000000;
 
-       devc->ADDR_WIDTH = buf[4] & 0x000000FF;
-       devc->ADDR_WIDTH |= (buf[5] << 8) & 0x0000FF00;
-       devc->ADDR_WIDTH |= (buf[6] << 16) & 0x00FF0000;
-       devc->ADDR_WIDTH |= (buf[7] << 24) & 0xFF000000;
+       devc->addr_width = buf[4] & 0x000000FF;
+       devc->addr_width |= (buf[5] << 8) & 0x0000FF00;
+       devc->addr_width |= (buf[6] << 16) & 0x00FF0000;
+       devc->addr_width |= (buf[7] << 24) & 0xFF000000;
 
-       uint8_t HOST_WORD_SIZE = 8;
+       const uint8_t host_word_size = 8;
 
-       devc->DATA_WIDTH_BYTES =
-               (devc->DATA_WIDTH + HOST_WORD_SIZE - 1) / HOST_WORD_SIZE;
-       devc->ADDR_WIDTH_BYTES =
-               (devc->ADDR_WIDTH + HOST_WORD_SIZE - 1) / HOST_WORD_SIZE;
+       devc->data_width_bytes =
+               (devc->data_width + host_word_size - 1) / host_word_size;
+       devc->addr_width_bytes =
+               (devc->addr_width + host_word_size - 1) / host_word_size;
 
-       devc->limit_samples_max = (0x01 << devc->ADDR_WIDTH);
+       devc->limit_samples_max = (0x01 << devc->addr_width);
        devc->limit_samples = devc->limit_samples_max;
 
-       devc->trigger_mask = g_malloc0(devc->DATA_WIDTH_BYTES);
-       devc->trigger_value = g_malloc0(devc->DATA_WIDTH_BYTES);
-       devc->trigger_mask_last = g_malloc0(devc->DATA_WIDTH_BYTES);
-       devc->trigger_value_last = g_malloc0(devc->DATA_WIDTH_BYTES);
-       devc->trigger_edge_mask = g_malloc0(devc->DATA_WIDTH_BYTES);
+       devc->trigger_mask = g_malloc0(devc->data_width_bytes);
+       devc->trigger_value = g_malloc0(devc->data_width_bytes);
+       devc->trigger_mask_last = g_malloc0(devc->data_width_bytes);
+       devc->trigger_value_last = g_malloc0(devc->data_width_bytes);
+       devc->trigger_edge_mask = g_malloc0(devc->data_width_bytes);
 }
 
 SR_PRIV struct dev_context *ipdbg_la_dev_new(void)
@@ -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;