--- 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 <stdint.h>
 
 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);
 
