summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2013-04-17 07:59:38 +0200
committerGerd Hoffmann <kraxel@redhat.com>2013-04-17 07:59:38 +0200
commit0ece5135fef56dbd0d94957c334655a57adb7212 (patch)
tree1c261acf4f8c69df7e12edfe1741c10eebebac65
parent6d5a429ab96363aeeb9a91a5ab8fddddf14e2aaa (diff)
downloadamtterm-0ece5135fef56dbd0d94957c334655a57adb7212.tar.gz
decode 0x29 message
Contributed by Donald Porter.
-rw-r--r--RedirectionConstants.h17
-rw-r--r--redir.c70
-rw-r--r--redir.h9
3 files changed, 75 insertions, 21 deletions
diff --git a/RedirectionConstants.h b/RedirectionConstants.h
index 8a7040c..6bd4fa5 100644
--- a/RedirectionConstants.h
+++ b/RedirectionConstants.h
@@ -24,9 +24,7 @@
#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_0x29 0x29 // encountered in the wild
-#define SOL_0x29_LENGTH 10
+#define SOL_CONTROLS_FROM_HOST 0x29 //Host to Console
#define SOL_DATA_FROM_HOST 0x2A //Host to Console
#define SOL_HEARTBEAT 0x2B
@@ -37,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
diff --git a/redir.c b/redir.c
index 03c0eac..313917b 100644
--- a/redir.c
+++ b/redir.c
@@ -298,6 +298,9 @@ int redir_sol_recv(struct redir *r)
return bshift;
}
+static int in_loopback_mode = 0;
+static int powered_off = 0;
+
int redir_data(struct redir *r)
{
int rc, bshift;
@@ -382,24 +385,55 @@ int redir_data(struct redir *r)
goto again;
redir_stop(r);
break;
- case SOL_0x29:
- bshift = SOL_0x29_LENGTH;
- if (r->blen < bshift)
- goto again;
- /* There is some data in this packet. Probably some port
- * reset data, flow control or whatever. I've seen the following:
- *
- * 0x29 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x06
- * 0x29 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x02 0x04
-
- * 0x29 0x00 0x00 0x00 0x91 0x00 0x00 0x00 0x00 0x00
- * 0x29 0x00 0x00 0x00 0x92 0x00 0x00 0x00 0x00 0x04
- *
- * It seems harmless to just ignore this stuff, the
- * redirection keeps working anyway.
- */
- 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]);
diff --git a/redir.h b/redir.h
index 7da393d..070559d 100644
--- a/redir.h
+++ b/redir.h
@@ -1,4 +1,5 @@
#include "RedirectionConstants.h"
+#include <stdint.h>
enum redir_state {
REDIR_NONE = 0,
@@ -38,6 +39,14 @@ struct redir {
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);