* 02110-1301, USA.
*/
+#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "tio/log.h"
#include "tio/error.h"
-static struct termios new_stdout, old_stdout, old_tio;
-static long rx_total = 0, tx_total = 0;
+static struct termios tio, new_stdout, old_stdout, old_tio;
+static unsigned long rx_total = 0, tx_total = 0;
static bool connected = false;
static bool tainted = false;
+static bool standard_baudrate = true;
static int fd;
+#ifndef BOTHER
+#define BOTHER 0010000
+#endif
+
#define tio_printf(format, args...) \
{ \
if (tainted) putchar('\n'); \
case KEY_I:
tio_printf("Settings information:");
tio_printf(" TTY device: %s", option.tty_device);
- tio_printf(" Baudrate: %d", option.baudrate);
+ tio_printf(" Baudrate: %u", option.baudrate);
tio_printf(" Databits: %d", option.databits);
tio_printf(" Flow: %s", option.flow);
tio_printf(" Stopbits: %d", option.stopbits);
case KEY_S:
/* Show tx/rx statistics upon ctrl-t s sequence */
tio_printf("Statistics:");
- tio_printf(" Sent %ld bytes, received %ld bytes", tx_total, rx_total);
+ tio_printf(" Sent %lu bytes, received %lu bytes", tx_total, rx_total);
*forward = false;
break;
default:
}
}
-void wait_for_tty_device(void)
+void stdout_configure(void)
+{
+ /* Save current stdout settings */
+ if (tcgetattr(STDOUT_FILENO, &old_stdout) < 0)
+ {
+ error_printf("Saving current stdio settings failed");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Prepare new stdout settings */
+ memset(&new_stdout, 0, sizeof(new_stdout));
+
+ /* Control, input, output, local modes for stdout */
+ new_stdout.c_cflag = 0;
+ new_stdout.c_iflag = 0;
+ new_stdout.c_oflag = 0;
+ new_stdout.c_lflag = 0;
+
+ /* Control characters */
+ new_stdout.c_cc[VTIME] = 0; /* Inter-character timer unused */
+ new_stdout.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
+
+ /* Activate new stdout settings */
+ tcsetattr(STDOUT_FILENO, TCSANOW, &new_stdout);
+ tcsetattr(STDOUT_FILENO, TCSAFLUSH, &new_stdout);
+
+ /* Print launch hints */
+ tio_printf("tio v%s", VERSION);
+ tio_printf("Press ctrl-t q to quit");
+
+ /* Make sure we restore old stdout settings on exit */
+ atexit(&stdout_restore);
+}
+
+void stdout_restore(void)
+{
+ tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdout);
+ tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdout);
+}
+
+void tty_configure(void)
+{
+ speed_t baudrate = 0;
+
+ memset(&tio, 0, sizeof(tio));
+
+ /* Set speed */
+ switch (option.baudrate)
+ {
+ /* The macro below expands into switch cases autogenerated by the
+ * configure script. Each switch case verifies and configures the baud
+ * rate and is of the form:
+ *
+ * case $baudrate: baudrate = B$baudrate; break;
+ *
+ * Only switch cases for baud rates detected supported by the host
+ * system are inserted.
+ *
+ * To see which baud rates are being probed see configure.ac
+ */
+ AUTOCONF_BAUDRATE_CASES
+
+ default:
+#if !HAVE_DECL_BOTHER
+ error_printf("Invalid baud rate");
+ exit(EXIT_FAILURE);
+#else
+ standard_baudrate = false;
+ break;
+#endif
+ }
+
+ if (standard_baudrate)
+ {
+ cfsetispeed(&tio, baudrate);
+ cfsetospeed(&tio, baudrate);
+ } else
+ {
+ tio.c_ispeed = tio.c_ospeed = baudrate;
+ tio.c_cflag &= ~CBAUD;
+ tio.c_cflag |= BOTHER;
+ }
+
+ /* Set databits */
+ tio.c_cflag &= ~CSIZE;
+ switch (option.databits)
+ {
+ case 5:
+ tio.c_cflag |= CS5;
+ break;
+ case 6:
+ tio.c_cflag |= CS6;
+ break;
+ case 7:
+ tio.c_cflag |= CS7;
+ break;
+ case 8:
+ tio.c_cflag |= CS8;
+ break;
+ default:
+ error_printf("Invalid data bits");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Set flow control */
+ if (strcmp("hard", option.flow) == 0)
+ {
+ tio.c_cflag |= CRTSCTS;
+ tio.c_iflag &= ~(IXON | IXOFF | IXANY);
+ }
+ else if (strcmp("soft", option.flow) == 0)
+ {
+ tio.c_cflag &= ~CRTSCTS;
+ tio.c_iflag |= IXON | IXOFF;
+ }
+ else if (strcmp("none", option.flow) == 0)
+ {
+ tio.c_cflag &= ~CRTSCTS;
+ tio.c_iflag &= ~(IXON | IXOFF | IXANY);
+ }
+ else
+ {
+ error_printf("Invalid flow control");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Set stopbits */
+ switch (option.stopbits)
+ {
+ case 1:
+ tio.c_cflag &= ~CSTOPB;
+ break;
+ case 2:
+ tio.c_cflag |= CSTOPB;
+ break;
+ default:
+ error_printf("Invalid stop bits");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Set parity */
+ if (strcmp("odd", option.parity) == 0)
+ {
+ tio.c_cflag |= PARENB;
+ tio.c_cflag |= PARODD;
+ }
+ else if (strcmp("even", option.parity) == 0)
+ {
+ tio.c_cflag |= PARENB;
+ tio.c_cflag &= ~PARODD;
+ }
+ else if (strcmp("none", option.parity) == 0)
+ tio.c_cflag &= ~PARENB;
+ else
+ {
+ error_printf("Invalid parity");
+ exit(EXIT_FAILURE);
+ }
+}
+
+void tty_wait_for_device(void)
{
fd_set rdfs;
int status;
}
}
-void configure_stdout(void)
-{
- /* Save current stdout settings */
- if (tcgetattr(STDOUT_FILENO, &old_stdout) < 0)
- {
- error_printf("Saving current stdio settings failed");
- exit(EXIT_FAILURE);
- }
-
- /* Prepare new stdout settings */
- bzero(&new_stdout, sizeof(new_stdout));
-
- /* Control, input, output, local modes for stdout */
- new_stdout.c_cflag = 0;
- new_stdout.c_iflag = 0;
- new_stdout.c_oflag = 0;
- new_stdout.c_lflag = 0;
-
- /* Control characters */
- new_stdout.c_cc[VTIME] = 0; /* Inter-character timer unused */
- new_stdout.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
-
- /* Activate new stdout settings */
- tcsetattr(STDOUT_FILENO, TCSANOW, &new_stdout);
- tcsetattr(STDOUT_FILENO, TCSAFLUSH, &new_stdout);
-
- /* Print launch hints */
- tio_printf("tio v%s", VERSION);
- tio_printf("Press ctrl-t + q to quit");
-
- /* Make sure we restore old stdout settings on exit */
- atexit(&restore_stdout);
-}
-
-void restore_stdout(void)
-{
- tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdout);
- tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdout);
-}
-
-void disconnect_tty(void)
+void tty_disconnect(void)
{
if (connected)
{
}
}
-void restore_tty(void)
+void tty_restore(void)
{
tcsetattr(fd, TCSANOW, &old_tio);
tcsetattr(fd, TCSAFLUSH, &old_tio);
if (connected)
- disconnect_tty();
+ tty_disconnect();
}
-int connect_tty(void)
+int tty_connect(void)
{
fd_set rdfs; /* Read file descriptor set */
int maxfd; /* Maximum file descriptor used */
/* Make sure device is of tty type */
if (!isatty(fd))
{
- error_printf_silent("Not a tty device");
- goto error_isatty;
+ error_printf("Not a tty device");
+ exit(EXIT_FAILURE);;
}
/* Lock device file */
/* Flush stale I/O data (if any) */
tcflush(fd, TCIOFLUSH);
+ /* Warn if non standard baud rate is used */
+ if (!standard_baudrate)
+ tio_printf("Warning: Using a non standard baud rate");
+
/* Print connect status */
tio_printf("Connected");
connected = true;
/* Make sure we restore tty settings on exit */
if (first)
{
- atexit(&restore_tty);
+ atexit(&tty_restore);
first = false;
}
/* Control, input, output, local modes for tty device */
- option.tio.c_cflag |= CLOCAL | CREAD;
- option.tio.c_oflag = 0;
- option.tio.c_lflag = 0;
+ tio.c_cflag |= CLOCAL | CREAD;
+ tio.c_oflag = 0;
+ tio.c_lflag = 0;
/* Control characters */
- option.tio.c_cc[VTIME] = 0; /* Inter-character timer unused */
- option.tio.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
+ tio.c_cc[VTIME] = 0; /* Inter-character timer unused */
+ tio.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
/* Activate new port settings */
- tcsetattr(fd, TCSANOW, &option.tio);
- tcsetattr(fd, TCSAFLUSH, &option.tio);
+ tcsetattr(fd, TCSANOW, &tio);
+ tcsetattr(fd, TCSAFLUSH, &tio);
maxfd = MAX(fd, STDIN_FILENO) + 1; /* Maximum bit entry (fd) to test */
return TIO_SUCCESS;
error_tcgetattr:
-error_isatty:
error_read:
- disconnect_tty();
+ tty_disconnect();
error_open:
return TIO_ERROR;
}