- com->socket redirection support added (initial SF patch #1107945 by Andrew Backer)

This commit is contained in:
Volker Ruppert 2005-07-10 16:51:09 +00:00
parent 2b1c95ff59
commit bff2c04c5b
3 changed files with 106 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: config.cc,v 1.36 2005-06-08 18:25:49 vruppert Exp $
// $Id: config.cc,v 1.37 2005-07-10 16:51:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -866,6 +866,7 @@ void bx_init_options ()
"term",
"raw",
"mouse",
"socket",
NULL
};
@ -880,7 +881,7 @@ void bx_init_options ()
strdup(descr),
(i==0)?1 : 0); // only enable the first by default
sprintf (name, "I/O mode of the serial device for COM%d", i+1);
sprintf (descr, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse'");
sprintf (descr, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket'");
bx_options.com[i].Omode = new bx_param_enum_c (
BXP_COMx_MODE(i+1),
strdup(name),

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: serial.cc,v 1.64 2005-01-19 18:21:37 sshwarts Exp $
// $Id: serial.cc,v 1.65 2005-07-10 16:51:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -38,6 +38,10 @@
#define BX_PLUGGABLE
#include "iodev.h"
#ifndef WIN32
#include <sys/socket.h>
#include <netdb.h>
#endif
#if USE_RAW_SERIAL
#include "serial_raw.h"
@ -83,7 +87,7 @@ bx_serial_c::~bx_serial_c(void)
fclose(BX_SER_THIS s[i].output);
break;
case BX_SER_MODE_TERM:
#if defined(SERIAL_ENABLE)
#if defined(SERIAL_ENABLE) && !defined(WIN32)
if (s[i].tty_id >= 0) {
tcsetattr(s[i].tty_id, TCSAFLUSH, &s[i].term_orig);
}
@ -94,6 +98,9 @@ bx_serial_c::~bx_serial_c(void)
delete [] BX_SER_THIS s[i].raw;
#endif
break;
case BX_SER_MODE_SOCKET:
if (BX_SER_THIS s[i].socket_id >= 0) ::close(BX_SER_THIS s[i].socket_id);
break;
}
}
}
@ -228,11 +235,11 @@ bx_serial_c::init(void)
BX_SER_THIS s[i].io_mode = BX_SER_MODE_FILE;
}
} else if (!strcmp(mode, "term")) {
#if defined(SERIAL_ENABLE)
#if defined(SERIAL_ENABLE) && !defined(WIN32)
if (strlen(bx_options.com[i].Odev->getptr ()) > 0) {
BX_SER_THIS s[i].tty_id = open(bx_options.com[i].Odev->getptr (), O_RDWR|O_NONBLOCK,600);
if (BX_SER_THIS s[i].tty_id < 0) {
BX_PANIC(("open of com%d (%s) failed\n", i+1, bx_options.com[i].Odev->getptr ()));
BX_PANIC(("open of com%d (%s) failed", i+1, bx_options.com[i].Odev->getptr ()));
} else {
BX_SER_THIS s[i].io_mode = BX_SER_MODE_TERM;
BX_DEBUG(("com%d tty_id: %d", i+1, BX_SER_THIS s[i].tty_id));
@ -273,6 +280,59 @@ bx_serial_c::init(void)
} else if (!strcmp(mode, "mouse")) {
BX_SER_THIS s[i].io_mode = BX_SER_MODE_MOUSE;
BX_SER_THIS mouse_port = i;
} else if (!strcmp(mode, "socket")) {
BX_SER_THIS s[i].io_mode = BX_SER_MODE_SOCKET;
struct sockaddr_in sin;
struct hostent *hp;
char host[BX_PATHNAME_LEN];
int port;
int socket;
#if defined(WIN32)
static bool winsock_init = false;
if (!winsock_init) {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD (2, 0);
err = WSAStartup (wVersionRequested, &wsaData);
if (err != 0)
BX_PANIC (("WSAStartup failed"));
winsock_init = true;
}
#endif
char *substr = strtok(bx_options.com[i].Odev->getptr(), ":");
strcpy(host, substr);
substr = strtok(NULL, ":");
if (!substr) {
BX_PANIC(("com%d: inet address is wrong (%s)", i+1,
bx_options.com[i].Odev->getptr ()));
}
port = atoi (substr);
hp = gethostbyname (host);
if (!hp) {
BX_PANIC(("com%d: gethostbyname failed (%s)", i+1, host));
}
memset ((char*) &sin, 0, sizeof (sin));
memcpy ((char*) &(sin.sin_addr), hp->h_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
sin.sin_port = htons (port);
socket = ::socket (AF_INET, SOCK_STREAM, 0);
if (socket < 0) {
BX_PANIC(("com%d: socket() failed",i+1));
}
if (::connect (socket, (sockaddr *) &sin, sizeof (sin)) < 0) {
socket = -1;
BX_INFO(("com%d: connect() failed (host:%s, port:%d)",i+1, host, port));
} else {
BX_INFO(("com%d - inet - socket_id: %d, ip:%s, port:%d", i+1, socket, host, port));
}
BX_SER_THIS s[i].socket_id = socket;
} else if (strcmp(mode, "null")) {
BX_PANIC(("unknown serial i/o mode"));
}
@ -1049,6 +1109,17 @@ bx_serial_c::tx_timer(void)
case BX_SER_MODE_MOUSE:
BX_INFO(("com%d: write to mouse ignored: 0x%02x", port+1, BX_SER_THIS s[port].tsrbuffer));
break;
case BX_SER_MODE_SOCKET:
if (BX_SER_THIS s[port].socket_id >= 0) {
#ifdef WIN32
BX_INFO(("attempting to write win32 : %c", BX_SER_THIS s[port].tsrbuffer));
::send(BX_SER_THIS s[port].socket_id,
(const char*) & BX_SER_THIS s[port].tsrbuffer, 1, 0);
#else
::write(BX_SER_THIS s[port].socket_id,
(bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1);
#endif
}
}
}
@ -1127,6 +1198,26 @@ bx_serial_c::rx_timer(void)
if ((BX_SER_THIS s[port].line_status.rxdata_ready == 0) ||
(BX_SER_THIS s[port].fifo_cntl.enable)) {
switch (BX_SER_THIS s[port].io_mode) {
case BX_SER_MODE_SOCKET:
#if defined(SERIAL_ENABLE)
if (BX_SER_THIS s[port].line_status.rxdata_ready == 0) {
tval.tv_sec = 0;
tval.tv_usec = 0;
FD_ZERO(&fds);
int socketid = BX_SER_THIS s[port].socket_id;
if (socketid >= 0) FD_SET(socketid, &fds);
if ((socketid >= 0) && (select(socketid+1, &fds, NULL, NULL, &tval) == 1)) {
#ifdef WIN32
(void) ::recv(socketid, (char*) &chbuf, 1, 0);
#else
(void) read(socketid, &chbuf, 1);
#endif
BX_INFO((" -- COM %d : read byte [%d]", port+1, chbuf));
data_ready = 1;
}
}
#endif
break;
case BX_SER_MODE_RAW:
#if USE_RAW_SERIAL
int data;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: serial.h,v 1.25 2004-12-05 20:23:39 vruppert Exp $
// $Id: serial.h,v 1.26 2005-07-10 16:51:09 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -36,6 +36,10 @@
# define BX_SER_THIS this->
#endif
#if defined(WIN32)
#define SERIAL_ENABLE
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) || defined(__APPLE__)
#define SERIAL_ENABLE
extern "C" {
@ -67,6 +71,7 @@ extern "C" {
#define BX_SER_MODE_TERM 2
#define BX_SER_MODE_RAW 3
#define BX_SER_MODE_MOUSE 4
#define BX_SER_MODE_SOCKET 5
enum {
BX_SER_INT_IER,
@ -109,12 +114,13 @@ typedef struct {
int io_mode;
int tty_id;
int socket_id;
FILE *output;
#if USE_RAW_SERIAL
serial_raw* raw;
#endif
#if defined(SERIAL_ENABLE)
#if defined(SERIAL_ENABLE) && !defined(WIN32)
struct termios term_orig, term_new;
#endif