tty-handler: Add baud rate setting
Add local-tty-baud setting for configuration file.
Optionally change tty baud rate using termios.
For errors, use prints to stderr where warn/error calls are not
appropriate (i.e. errno hasn't been set by the error-causing call).
Fixes openbmc/openbmc#992.
Change-Id: Ia9226d1666f2626b2c04f30297755d93aee4994e
Signed-off-by: Xo Wang <xow@google.com>
diff --git a/tty-handler.c b/tty-handler.c
index 00ada7a..e640354 100644
--- a/tty-handler.c
+++ b/tty-handler.c
@@ -21,7 +21,9 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#include <termios.h>
#include "console-server.h"
@@ -32,6 +34,11 @@
int fd;
};
+struct terminal_speed_name {
+ speed_t speed;
+ const char *name;
+};
+
static struct tty_handler *to_tty_handler(struct handler *handler)
{
return container_of(handler, struct tty_handler, handler);
@@ -59,11 +66,88 @@
return POLLER_OK;
}
+static int baud_string_to_speed(speed_t *speed, const char *baud_string) {
+ const struct terminal_speed_name terminal_speeds[] = {
+ { B50, "50" },
+ { B75, "75" },
+ { B110, "110" },
+ { B134, "134" },
+ { B150, "150" },
+ { B200, "200" },
+ { B300, "300" },
+ { B600, "600" },
+ { B1200, "1200" },
+ { B1800, "1800" },
+ { B2400, "2400" },
+ { B4800, "4800" },
+ { B9600, "9600" },
+ { B19200, "19200" },
+ { B38400, "38400" },
+ { B57600, "57600" },
+ { B115200, "115200" },
+ { B230400, "230400" },
+ { B460800, "460800" },
+ { B500000, "500000" },
+ { B576000, "576000" },
+ { B921600, "921600" },
+ { B1000000, "1000000" },
+ { B1152000, "1152000" },
+ { B1500000, "1500000" },
+ { B2000000, "2000000" },
+ { B2500000, "2500000" },
+ { B3000000, "3000000" },
+ { B3500000, "3500000" },
+ { B4000000, "4000000" },
+ };
+ const size_t num_terminal_speeds = sizeof(terminal_speeds) /
+ sizeof(struct terminal_speed_name);
+ size_t i;
+
+ for (i = 0; i < num_terminal_speeds; i++) {
+ if (strcmp(baud_string, terminal_speeds[i].name) == 0) {
+ *speed = terminal_speeds[i].speed;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int set_terminal_baud(struct tty_handler *th, const char *tty_name,
+ const char *desired_baud) {
+ struct termios term_options;
+ speed_t speed;
+
+ if (baud_string_to_speed(&speed, desired_baud) != 0) {
+ fprintf(stderr, "%s is not a valid baud rate for terminal %s\n",
+ desired_baud, tty_name);
+ return -1;
+ }
+
+ if (tcgetattr(th->fd, &term_options) < 0) {
+ warn("Can't get config for %s", tty_name);
+ return -1;
+ }
+
+ if (cfsetspeed(&term_options, speed) < 0) {
+ warn("Couldn't set speeds for %s", tty_name);
+ return -1;
+ }
+
+ if (tcsetattr(th->fd, TCSAFLUSH, &term_options) < 0) {
+ warn("Couldn't commit terminal options for %s", tty_name);
+ return -1;
+ }
+ printf("Set %s terminal baud rate to %s\n", tty_name, desired_baud);
+
+ return 0;
+}
+
static int tty_init(struct handler *handler, struct console *console,
struct config *config __attribute__((unused)))
{
struct tty_handler *th = to_tty_handler(handler);
const char *tty_name;
+ const char *tty_baud;
char *tty_path;
int rc, flags;
@@ -89,6 +173,12 @@
flags |= FNDELAY;
fcntl(th->fd, F_SETFL, flags);
+ tty_baud = config_get_value(config, "local-tty-baud");
+ if (tty_baud != NULL)
+ if (set_terminal_baud(th, tty_name, tty_baud) != 0)
+ fprintf(stderr, "Couldn't set baud rate for %s to %s\n",
+ tty_name, tty_baud);
+
th->poller = console_register_poller(console, handler, tty_poll,
th->fd, POLLIN, NULL);
th->console = console;