[SerialICE] Patch set updated for serialice: qemu-0.15.x/serialice-com: Implement TCP serialice connection

Patrick Rudolph (siro@das-labor.org) gerrit at coreboot.org
Thu Apr 28 14:20:02 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 37bf6de3a26fa15303152d0e744847bc59fc1462
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
    
    Add support for TCP connections.
    Useful to connect to BeagleBone Black in EHCI Debug mode using
    ser2net daemon.
    Pass tcp:hostname:port instead of tty device path.
    Example:
    ./qemu -M serialice -serialice tcp:10.0.0.1:8888
    
    The windows version hasn't been tested yet.
    
    Change-Id: Iee264dfd11375e11c02ea25b6887d32f3db887c5
    Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
 SerialICE/README.QEMU       |   7 ++
 qemu-0.15.x/serialice-com.c | 177 ++++++++++++++++++++++++++++++++------------
 2 files changed, 138 insertions(+), 46 deletions(-)

diff --git a/SerialICE/README.QEMU b/SerialICE/README.QEMU
index 3af8c36..b9d2a96 100644
--- a/SerialICE/README.QEMU
+++ b/SerialICE/README.QEMU
@@ -47,6 +47,13 @@ $ i386-softmmu/qemu -M serialice -serialice \
 The device /dev/ttyS0 is the name of the serial device connected to your target
 machine running the SerialICE shell.
 
+Instead of a local serial device you can connect over TCP to a BeagleBone Black
+running a ser2tcp server.
+The command to connect to a remote host at 10.0.0.1 port 8080 is:
+
+$ i386-softmmu/qemu -M serialice -serialice \
+	tcp:10.0.0.1:8080 -hda /dev/zero -L ./bios
+
 For debugging hints see the file README.GDB
 
 ADAPTING THE CODE
diff --git a/qemu-0.15.x/serialice-com.c b/qemu-0.15.x/serialice-com.c
index 9211b6f..85172d0 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;
@@ -114,6 +118,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++) {
         c = 0;
@@ -207,6 +212,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) {
@@ -217,69 +226,145 @@ 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 && tmp == serialice_device) {
+            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 from hostname string */
+                *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);
+    if (s->tcp) {
+        int ret;
+        WSADATA wsaData = {0};
+        ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
+        if (ret) {
+            perror("WSAStartup failed: %d\n", ret);
+            exit(1);
+        }
 
-    if (s->fd == INVALID_HANDLE_VALUE) {
-        perror("SerialICE: Could not connect to target TTY");
-        exit(1);
-    }
+        s->fd = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
+        if (s->fd == INVALID_SOCKET) {
+            perror("SerialICE: Could not create a TCP socket");
+            exit(1);
+        }
+    } else {
+        s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
+                           0, NULL, OPEN_EXISTING, 0, NULL);
+        if (s->fd == INVALID_HANDLE_VALUE) {
+            perror("SerialICE: Could not connect to target TTY");
+            exit(1);
+        }
 
-    DCB dcb;
-    if (!GetCommState(s->fd, &dcb)) {
-        perror("SerialICE: Could not load config for target TTY");
-        exit(1);
-    }
+        DCB dcb;
+        if (!GetCommState(s->fd, &dcb)) {
+            perror("SerialICE: Could not load config for target TTY");
+            exit(1);
+        }
 
-    dcb.BaudRate = CBR_115200;
-    dcb.ByteSize = 8;
-    dcb.Parity = NOPARITY;
-    dcb.StopBits = ONESTOPBIT;
+        dcb.BaudRate = CBR_115200;
+        dcb.ByteSize = 8;
+        dcb.Parity = NOPARITY;
+        dcb.StopBits = ONESTOPBIT;
 
-    if (!SetCommState(s->fd, &dcb)) {
-        perror("SerialICE: Could not store config for target TTY");
-        exit(1);
+        if (!SetCommState(s->fd, &dcb)) {
+            perror("SerialICE: Could not store config for target TTY");
+            exit(1);
+        }
     }
 #else
-    s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+    if (s->tcp) {
+        struct timeval tv;
+        s->fd = socket(AF_INET, SOCK_STREAM, 0);
+        if (s->fd == -1) {
+            perror("SerialICE: Could not create a TCP socket");
+            exit(1);
+        }
 
-    if (s->fd == -1) {
-        perror("SerialICE: Could not connect to target TTY");
-        exit(1);
-    }
+        if (fcntl(s->fd, F_SETFL, 0) == -1) {
+            perror("SerialICE: Could not switch to blocking I/O");
+            exit(1);
+        }
 
-    if (ioctl(s->fd, TIOCEXCL) == -1) {
-        perror("SerialICE: TTY not exclusively available");
-        exit(1);
-    }
+        tv.tv_sec = 1;  /* 1 second timeout */
+        tv.tv_usec = 0;
+        setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
+    } 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 (fcntl(s->fd, F_SETFL, 0) == -1) {
-        perror("SerialICE: Could not switch to blocking I/O");
-        exit(1);
-    }
+        if (ioctl(s->fd, TIOCEXCL) == -1) {
+            perror("SerialICE: TTY not exclusively available");
+            exit(1);
+        }
 
-    if (tcgetattr(s->fd, &options) == -1) {
-        perror("SerialICE: Could not get TTY attributes");
-        exit(1);
-    }
+        if (fcntl(s->fd, F_SETFL, 0) == -1) {
+            perror("SerialICE: Could not switch to blocking I/O");
+            exit(1);
+        }
 
-    cfsetispeed(&options, B115200);
-    cfsetospeed(&options, B115200);
+        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;
+        /* 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);
+        tcsetattr(s->fd, TCSANOW, &options);
 
-    tcflush(s->fd, TCIOFLUSH);
+        tcflush(s->fd, TCIOFLUSH);
+    }
 #endif
 
+    if (s->tcp) {
+        struct hostent *server;
+        struct sockaddr_in serv_addr;
+
+        server = gethostbyname(hostname);
+        if (server == NULL) {
+            perror("No such host.\n");
+            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);
+
+        printf("Connecting to tcp://%s:%d ...\n", hostname, port);
+
+        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);
+    }
+
     s->buffer = mallocz(BUFFER_SIZE);
     s->command = mallocz(BUFFER_SIZE);
     if (!s->buffer || !s->command) {



More information about the SerialICE mailing list