[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