--- RedirectionConstants.h 2011-05-26 05:19:45.000000000 -0400 +++ RedirectionConstants.h 2013-12-05 18:32:54.800377337 -0500 @@ -24,6 +24,8 @@ #define SOL_KEEP_ALIVE_PING 0x24 //Console to Host #define SOL_KEEP_ALIVE_PONG 0x25 //Host to Console #define SOL_DATA_TO_HOST 0x28 //Console to host +#define SOL_CONTROLS_FROM_HOST 0x29 //Host to Console + #define SOL_DATA_FROM_HOST 0x2A //Host to Console #define SOL_HEARTBEAT 0x2B @@ -33,6 +35,19 @@ #define END_SOL_REDIRECTION_LENGTH 8 #define END_SOL_REDIRECTION_REPLY_LENGTH 8 +// Control message control bits (message 0x29) +#define RTS_CONTROL 1 +#define DTR_CONTROL 2 +#define BREAK_CONTROL 4 + +// Control message status bits (message 0x29) +#define TX_OVERFLOW 1 +#define LOOPBACK_ACTIVE 2 +#define SYSTEM_POWER_STATE 4 +#define RX_FLUSH_TIMEOUT 8 +#define TESTMODE_ACTIVE 16 + + //IDER Messages Formats #define START_IDER_REDIRECTION 0x40 #define START_IDER_REDIRECTION_REPLY 0x41 --- redir.c.orig 2011-05-26 05:19:45.000000000 -0400 +++ redir.c 2013-12-05 18:32:54.824386101 -0500 @@ -298,6 +302,9 @@ return bshift; } +static int in_loopback_mode = 0; +static int powered_off = 0; + int redir_data(struct redir *r) { int rc, bshift; @@ -382,6 +389,55 @@ goto again; redir_stop(r); break; + case SOL_CONTROLS_FROM_HOST: { + bshift = r->blen; /* FIXME */ + if (r->blen < bshift) + goto again; + + /* Host sends this message to the Management Console when + * the host has changed its COM port control lines. This + * message is likely to be one of the first messages that + * the Host sends to the Console after it starts SOL + * redirection. + */ + struct controls_from_host_message *msg = (struct controls_from_host_message *) r->buf; + //printf("Type %x, control %d, status %d\n", msg->type, msg->control, msg->status); + if (msg->status & LOOPBACK_ACTIVE) { + if (r->verbose) + fprintf (stderr, "Warning, SOL device is running in loopback mode. Text input may not be accepted\n"); + in_loopback_mode = 1; + } else if (in_loopback_mode) { + if (r->verbose) + fprintf (stderr, "SOL device is no longer running in loopback mode\n"); + in_loopback_mode = 0; + } + + if (0 == (msg->status & SYSTEM_POWER_STATE)) { + if (r->verbose) + fprintf (stderr, "The system is powered off.\n"); + powered_off = 1; + } else if (powered_off) { + if (r->verbose) + fprintf (stderr, "The system is powered on.\n"); + powered_off = 0; + } + + if (r->verbose) { + if (msg->status & (TX_OVERFLOW|RX_FLUSH_TIMEOUT|TESTMODE_ACTIVE)) + fprintf (stderr, "Other unhandled status condition\n"); + + if (msg->control & RTS_CONTROL) + fprintf (stderr, "RTS is asserted on the COM Port\n"); + + if (msg->control & DTR_CONTROL) + fprintf (stderr, "DTR is asserted on the COM Port\n"); + + if (msg->control & BREAK_CONTROL) + fprintf (stderr, "BREAK is asserted on the COM Port\n"); + } + + break; + } default: snprintf(r->err, sizeof(r->err), "%s: unknown r->buf 0x%02x", __FUNCTION__, r->buf[0]); --- redir.h 2011-05-26 05:19:45.000000000 -0400 +++ redir.h 2013-12-05 18:32:54.825382282 -0500 @@ -1,4 +1,5 @@ #include "RedirectionConstants.h" +#include enum redir_state { REDIR_NONE = 0, @@ -38,6 +39,14 @@ int (*cb_recv)(void *cb_data, unsigned char *buf, int len); }; +struct __attribute__ ((__packed__)) controls_from_host_message { + unsigned char type; // 0x29 + unsigned char reserved[3]; + uint32_t host_sequence_number; + unsigned char control; + unsigned char status; +}; + const char *redir_state_name(enum redir_state state); const char *redir_state_desc(enum redir_state state);