[SerialICE] New patch to review for serialice: qemu-0.15.x/serialice-com: Implement TCP serialice connection

Patrick Rudolph (siro@das-labor.org) gerrit at coreboot.org
Mon Apr 25 19:25:25 CEST 2016


Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14512

-gerrit

commit f4ac7545c289c59c307e297258bfc56db8585930
Author: Patrick Rudolph <siro at das-labor.org>
Date:   Mon Apr 25 12:26:12 2016 +0200

    qemu-0.15.x/serialice-com: Implement TCP serialice connection
    
    Pass tcp:hostname:port instead of tty device path.
    Example:
    ./qemu -M serialice -serialice tcp:10.1.0.1:8888
    
    Connects to the target using TCP socket (unix only).
    Useful to connect to BeagleBone Black in EHCI Debug mode using
    ser2net daemon on port 8888.
    
    Change-Id: Iee264dfd11375e11c02ea25b6887d32f3db887c5
    Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
 qemu-0.15.x/serialice-com.c | 128 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 100 insertions(+), 28 deletions(-)

diff --git a/qemu-0.15.x/serialice-com.c b/qemu-0.15.x/serialice-com.c
index 25ccaf5..1fa95c2 100644
--- a/qemu-0.15.x/serialice-com.c
+++ b/qemu-0.15.x/serialice-com.c
@@ -34,6 +34,9 @@
 #include <fcntl.h>
 #include <termios.h>
 #include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #endif
 
 #include <serialice.h>
@@ -47,6 +50,7 @@ typedef struct {
 #else
     int fd;
 #endif
+    int tcp;
     char *buffer;
     char *command;
 } SerialICEState;
@@ -113,6 +117,7 @@ static int serialice_write(SerialICEState * state, const void *buf,
     char *buffer = (char *)buf;
     char c;
     int i;
+    int err;
 
     for (i = 0; i < (int)nbyte; i++) {
 #ifdef WIN32
@@ -125,8 +130,14 @@ static int serialice_write(SerialICEState * state, const void *buf,
             ReadFile(state->fd, &c, 1, &ret, NULL);
         }
 #else
-        while (write(state->fd, buffer + i, 1) != 1) ;
-        while (read(state->fd, &c, 1) != 1) ;
+        while ((err = write(state->fd, buffer + i, 1)) != 1) {
+            if (err == -1)
+                return -1;
+        }
+        while ((err = read(state->fd, &c, 1)) != 1) {
+            if (err == -1)
+                return -1;
+        }
 #endif
         if (c != buffer[i] && !handshake_mode) {
             printf("Readback error! %x/%x\n", c, buffer[i]);
@@ -193,6 +204,10 @@ static int serialice_wait_prompt(void)
 
 const SerialICE_target *serialice_serial_init(void)
 {
+    int len = 0;
+    int port = 0;
+    char *hostname = NULL;
+
     s = mallocz(sizeof(SerialICEState));
 
     if (!s) {
@@ -203,6 +218,24 @@ const SerialICE_target *serialice_serial_init(void)
         printf("You need to specify a serial device to use SerialICE.\n");
         exit(1);
     }
+    len = strlen(serialice_device);
+    if (len > 5) {
+        char *tmp = strstr(serialice_device, "tcp:");
+        if (tmp) {
+            hostname = mallocz(len - 4 + 1);
+            /* copy hostname and port */
+            memcpy(hostname, tmp + 4, len - 4);
+            /* search for port */
+            tmp = strstr(hostname, ":");
+            if (tmp) {
+                /* cut of port */
+                *tmp = 0;
+                /* read port */
+                port = atoi(tmp + 1);
+                s->tcp = !!port;
+            }
+        }
+    }
 #ifdef WIN32
     s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
                        0, NULL, OPEN_EXISTING, 0, NULL);
@@ -228,44 +261,83 @@ const SerialICE_target *serialice_serial_init(void)
         exit(1);
     }
 #else
-    s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
-
+    if (s->tcp) {
+        s->fd = socket(AF_INET, SOCK_STREAM, 0);
+    } else {
+        s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+    }
     if (s->fd == -1) {
         perror("SerialICE: Could not connect to target TTY");
         exit(1);
     }
 
-    if (ioctl(s->fd, TIOCEXCL) == -1) {
-        perror("SerialICE: TTY not exclusively available");
-        exit(1);
-    }
+    if (s->tcp) {
+        struct timeval tv;
+        struct hostent *server;
+        struct sockaddr_in serv_addr;
 
-    if (fcntl(s->fd, F_SETFL, 0) == -1) {
-        perror("SerialICE: Could not switch to blocking I/O");
-        exit(1);
-    }
+        server = gethostbyname(hostname);
+        if (server == NULL) {
+            perror("No such host.\n");
+            exit(1);
+        }
 
-    if (tcgetattr(s->fd, &options) == -1) {
-        perror("SerialICE: Could not get TTY attributes");
-        exit(1);
-    }
+        bzero((char *) &serv_addr, sizeof(serv_addr));
+        serv_addr.sin_family = AF_INET;
+        bcopy((char *)server->h_addr,
+             (char *)&serv_addr.sin_addr.s_addr,
+             server->h_length);
+        serv_addr.sin_port = htons(port);
 
-    cfsetispeed(&options, B115200);
-    cfsetospeed(&options, B115200);
+        printf("Connecting to tcp://%s:%d ...\n", hostname, port);
 
-    /* set raw input, 1 second timeout */
-    options.c_cflag |= (CLOCAL | CREAD);
-    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
-    options.c_oflag &= ~OPOST;
-    options.c_iflag |= IGNCR;
-    options.c_cc[VMIN] = 0;
-    options.c_cc[VTIME] = 100;
+        if (connect(s->fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+            perror("ERROR connecting");
+            exit(1);
+        }
+        printf("Connected to tcp://%s:%d .\n", hostname, port);
 
-    tcsetattr(s->fd, TCSANOW, &options);
+        if (fcntl(s->fd, F_SETFL, 0) == -1) {
+            perror("SerialICE: Could not switch to blocking I/O");
+            exit(1);
+        }
 
-    tcflush(s->fd, TCIOFLUSH);
-#endif
+        tv.tv_sec = 3;  /* 1 Secs Timeout */
+        tv.tv_usec = 0;
+
+        setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
+    } else {
+        if (ioctl(s->fd, TIOCEXCL) == -1) {
+            perror("SerialICE: TTY not exclusively available");
+            exit(1);
+        }
+
+        if (fcntl(s->fd, F_SETFL, 0) == -1) {
+            perror("SerialICE: Could not switch to blocking I/O");
+            exit(1);
+        }
+
+        if (tcgetattr(s->fd, &options) == -1) {
+            perror("SerialICE: Could not get TTY attributes");
+            exit(1);
+        }
+
+        cfsetispeed(&options, B115200);
+        cfsetospeed(&options, B115200);
 
+        /* set raw input, 1 second timeout */
+        options.c_cflag |= (CLOCAL | CREAD);
+        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+        options.c_oflag &= ~OPOST;
+        options.c_iflag |= IGNCR;
+        options.c_cc[VMIN] = 0;
+        options.c_cc[VTIME] = 100;
+
+        tcsetattr(s->fd, TCSANOW, &options);
+
+        tcflush(s->fd, TCIOFLUSH);
+    }
+#endif
     s->buffer = mallocz(BUFFER_SIZE);
     s->command = mallocz(BUFFER_SIZE);
     if (!s->buffer || !s->command) {



More information about the SerialICE mailing list