r2629 - in developers/werner: . neocon

werner at sita.openmoko.org werner at sita.openmoko.org
Sat Aug 4 08:02:26 CEST 2007


Author: werner
Date: 2007-08-04 08:02:22 +0200 (Sat, 04 Aug 2007)
New Revision: 2629

Added:
   developers/werner/neocon/
   developers/werner/neocon/Makefile
   developers/werner/neocon/README
   developers/werner/neocon/neocon.c
Log:
A simple interface for tty devices that pop in and out of existence.



Added: developers/werner/neocon/Makefile
===================================================================
--- developers/werner/neocon/Makefile	2007-08-04 04:16:28 UTC (rev 2628)
+++ developers/werner/neocon/Makefile	2007-08-04 06:02:22 UTC (rev 2629)
@@ -0,0 +1,16 @@
+PREFIX=/usr/local
+
+CFLAGS=-Wall -g
+
+.PHONY:	all clean install uninstall
+
+all:		neocon
+
+clean:
+		rm -f neocon
+
+install:	neocon
+		install -m 555 neocon $(PREFIX)/bin
+
+uninstall:
+		rm -f $(PREFIX)/bin/neocon

Added: developers/werner/neocon/README
===================================================================
--- developers/werner/neocon/README	2007-08-04 04:16:28 UTC (rev 2628)
+++ developers/werner/neocon/README	2007-08-04 06:02:22 UTC (rev 2629)
@@ -0,0 +1,9 @@
+"neocon" is a simple serial console utility that tries to open a
+ttys that may exist on a system until one such open succeeds. It
+then passes terminal input and output, until there is a read or
+write failure on the tty, in which case it disconnects, and the
+process restarts.
+
+This is mainly intended for serial over USB interfaces that
+disappear when the Neo or debug board is restarted. E.g.,
+neocon /dev/ttyUSB0 /dev/ttyUSB1

Added: developers/werner/neocon/neocon.c
===================================================================
--- developers/werner/neocon/neocon.c	2007-08-04 04:16:28 UTC (rev 2628)
+++ developers/werner/neocon/neocon.c	2007-08-04 06:02:22 UTC (rev 2629)
@@ -0,0 +1,224 @@
+/*
+ * neocon.c - An interface for changing tty devices
+ *
+ * Copyright (C) 2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner at openmoko.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/select.h>
+
+static char *const *ttys;
+static int num_ttys;
+static int bps = B115200;
+static struct termios console, tty;
+
+
+static void make_raw(int fd, struct termios *old)
+{
+    struct termios t;
+    long flags;
+
+    if (tcgetattr(fd, &t) < 0) {
+	perror("tcgetattr");
+	exit(1);
+    }
+    if (old)
+	*old = t;
+    cfmakeraw(&t);
+    if (fd) {
+	t.c_iflag  &= ~(IXON | IXOFF);
+	t.c_cflag |= CLOCAL;
+	t.c_cflag &= ~CRTSCTS;
+	if (cfsetispeed(&t, bps) < 0) {
+	    perror("cfsetispeed");
+	    exit(1);
+	}
+	if (cfsetospeed(&t, bps) < 0) {
+	    perror("cfsetospeed");
+	    exit(1);
+	}
+    }
+    if (tcsetattr(fd, TCSANOW, &t) < 0) {
+	perror("tcsetattr");
+	exit(1);
+    }
+    flags = fcntl(fd,F_GETFL);
+    if (flags < 0) {
+	perror("fcntl F_GETFL");
+	exit(1);
+    }
+    if (fcntl(fd,F_SETFL,flags & ~O_NONBLOCK) < 0) {
+	perror("fcntl F_GETFL");
+	exit(1);
+    }
+}
+
+
+static int open_first_tty(void)
+{
+    int i, fd = -1;
+
+    for (i = 0; i != num_ttys; i++) {
+	fd = open(ttys[i], O_RDWR | O_NDELAY);
+	if (fd >= 0)
+	    break;
+    }
+    if (fd >= 0)
+	make_raw(fd, &tty);
+    return fd;
+}
+
+
+static void scan(const char *s, size_t len)
+{
+    static int state = 0;
+    size_t i;
+
+    for (i = 0; i != len; i++)
+	switch (state) {
+	    case 0:
+		if (s[i] == '~')
+		    state++;
+		else
+		    state = 0;
+		break;
+	    case 1:
+		if (s[i] == '.')
+		    exit(0);
+		state = 0;
+		break;
+	}
+}
+
+
+static int copy(int in, int out, int scan_escape)
+{
+    char buffer[2048];
+    ssize_t got, wrote, pos;
+ 
+    got = read(in, buffer, sizeof(buffer));
+    if (got < 0)
+	return 0;
+    if (scan_escape)
+	scan(buffer, got);
+    for (pos = 0; pos != got; pos += wrote) {
+	wrote = write(out, buffer+pos, got-pos);
+	if (wrote < 0)
+	    return 0;
+    }
+    return 1;
+}
+
+
+static void write_string(const char *s)
+{
+    int len = strlen(s);
+
+    while (len) {
+	ssize_t wrote;
+
+	wrote = write(1, s, len);
+	if (wrote < 0) {
+	    perror("write");
+	    exit(1);
+	}
+	s += wrote;
+	len -= wrote;
+    }
+}
+
+
+static void cleanup(void)
+{
+    if (tcsetattr(0, TCSANOW, &console) < 0)
+	perror("tcsetattr");
+}
+
+
+static void usage(const char *name)
+{
+    fprintf(stderr, "usage: %s [-b bps] tty ...\n", name);
+    exit(1);
+}
+
+
+int main(int argc, char *const *argv)
+{
+    char *end;
+    int c;
+    int fd = -1;
+
+    while ((c = getopt(argc, argv, "")) != EOF)
+	switch (c) {
+	    case 'b':
+		bps = strtoul(optarg, &end, 0);
+		if (!*end)
+		    usage(*argv);
+		break;
+	    default:
+		usage(*argv);
+	}
+    num_ttys = argc-optind;
+    ttys = argv+optind;
+
+    make_raw(0, &console);
+    atexit(cleanup);
+    while (1) {
+	struct timeval tv;
+	fd_set set;
+	int res;
+
+	if (fd < 0) {
+	    fd = open_first_tty();
+	    if (fd > 0)
+		write_string("\r\n[Open]\r\n");
+	}
+	FD_ZERO(&set);
+	FD_SET(0, &set);
+	if (fd >= 0)
+	    FD_SET(fd, &set);
+	tv.tv_sec = 0;
+	tv.tv_usec = 100000;
+	res = select(fd < 0 ? 1 : fd+1, &set, NULL, NULL, &tv);
+	if (res < 0) {
+	    perror("select");
+	    return 1;
+	}
+	if (FD_ISSET(0, &set))
+	    if (!copy(0, fd, 1))
+		goto failed;
+	if (fd >= 0 && FD_ISSET(fd, &set))
+	    if (!copy(fd, 1, 0))
+		goto failed;
+	continue;
+
+failed:
+	write_string("\r\n[Closed]\r\n");
+	(void) close(fd);
+	fd = -1;
+    }
+    return 0;
+}





More information about the commitlog mailing list