
#include <sys/ioctl.h>
#include <termios.h>
int n_bytes;
if (ioctl(fd, FIONREAD, &n_bytes) < 0) {
/* handle error */
}
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int write_to(const char * fname, int fd, const char * msg)
{
const char * p = msg;
int n_bytes = strlen(msg);
while (n_bytes) {
int r = write(fd, p, n_bytes);
if (r < 0) {
fprintf(stderr, "write %s failed: %d %s\n", fname, errno, strerror(errno));
return 1;
}
if (r == 0) {
// network sockets may return a 0-byte write; files never should
fprintf(stderr, "write %s: unexpected network behavior\n", fname);
return 1;
}
n_bytes -= r;
p += r;
}
return 0;
}
const char uart_device[] = "/dev/ttyACM0";
int uart_connect(int fd)
{
struct timeval t_start;
gettimeofday(&t_start, 0 /*tz*/);
int request_sent = 0, n_bytes;
char buf[4096];
while (1) {
struct timespec t_out;
struct timeval t_now;
gettimeofday(&t_now, 0 /*tz*/);
t_out.tv_nsec = (t_start.tv_usec - t_now.tv_usec + 1000000)*1000L;
t_out.tv_sec = t_start.tv_sec - t_now.tv_sec;
if (t_out.tv_nsec >= 1000000000L) {
t_out.tv_nsec -= 1000000000L;
t_out.tv_sec++;
}
fd_set rfds, wfds, efds;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
FD_SET(fd, &rfds);
int r = pselect(fd + 1, &rfds, &wfds, &efds, &t_out, 0 /*sigmask*/);
if (r == -1) {
fprintf(stderr, "%s: pselect failed %d %s\n", uart_device, errno, strerror(errno));
return 1;
}
if (r == 0) {
if (request_sent) {
// waited 1 s for response, time out
fprintf(stderr, "timeout waiting for %s\n", uart_device);
return 1;
}
// send request after waiting for 1 s
request_sent = 1;
if (write_to(uart_device, fd, "AT\n")) return 1;
fprintf(stderr, "write AT\n");
gettimeofday(&t_start, 0 /*tz*/);
}
if (FD_ISSET(fd, &rfds)) {
if (ioctl(fd, FIONREAD, &n_bytes) < 0) {
fprintf(stderr, "FIONREAD failed: %d %s\n", errno, strerror(errno));
return 1;
}
if (n_bytes > (int) sizeof(buf)) n_bytes = (int) sizeof(buf);
r = read(fd, buf, n_bytes);
if (r < 0) {
fprintf(stderr, "read %s failed: %d %s\n", uart_device, errno, strerror(errno));
return 1;
}
buf[r] = 0;
fprintf(stderr, "read %d bytes: \"%s\"\n", r, buf);
}
}
return 0;
}
int main()
{
int fd = open(uart_device, O_RDWR);
if (fd == -1) {
fprintf(stderr, "unable to connect: %d %s\n", errno, strerror(errno));
return 1;
}
if (uart_connect(fd)) {
close(fd);
return 1;
}
close(fd);
return 0;
}
#!/bin/bash
if [ -z "$1" ]; then
ping 2$gt;&1 | sed -e "s/ping/`basename $0`/g"
exit 1
fi
signalpingchild()
{
for a in 1 2 3 4; do ps -f $gt;/dev/null; done
}
trap signalpingchild INT TERM HUP QUIT
ping -s18 -n $1 | while read a; do
[ "${a#PING $1}" != "$a" -o -z "$a" ] && continue
if [ "${a%statistics ---}" != "$a" ]; then
echo ""
echo "$a"
cat
break
fi
if [ "${a/icmp_seq/}" == "$a" ]; then
echo -ne "\r\e[K"
echo "$a"
continue
fi
v="`echo \"$a\" | awk '{ d=$4; sub(":\$", "", d); \
t=$7; sub("^time=", "", t); \
x=log(t) + 3; if (x $gt; 5) x = x*16 - 16*5; \
print "b=" $1 "; d=\\\"" d "\\\"; " $6 "; t=\\\"" t "\\\"; x=" x "; s=\\\"" $8 "\\\""; \
}'`"
eval "$v"
if [ $b -ne $((18+8)) -o "$d" != "$1" -o "$s" != "ms" ]; then
echo "$a: bad $v"
continue
fi
# pretty-print
echo -ne '\r\e[K' | awk "{
t=$t;
if (t<1000) { u=\"m\" }
else if (t<1000000) { u=\"\"; t /= 1000 };
for (x=0; x<$x; x++) b=b \"=\";
printf \"%s%7.3f %ss %s\", \$0, t, u, b;
exit}"
done &
wait $! # this convinces ping it is connected to a tty
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define winsize __termios__winsize
#define termio __termios__termio
#include <linux/termios.h>
/*
* TIOCMSET and TIOCMGET are POSIX
* TIOCMODS and TIOCMODG are BSD (4.3 ?)
* MCSETA and MCGETA are HPUX
*/
int do_set(int fd, const char * bitstr, int bit, int on)
{
if (bit == 0) {
fprintf(stderr, "set(%s = %d): invalid bit\n", bitstr, on);
return 1;
}
if (ioctl(fd, (on ? TIOCMBIS : TIOCMBIC), &bit)) {
fprintf(stderr, "set(%s = %d) failed: %d %s\n", bitstr, on, errno, strerror(errno));
return 1;
}
if (bit == TIOCM_CTS || bit == TIOCM_CAR || bit == TIOCM_RNG || bit == TIOCM_DSR)
printf("set(%s = %d) warning: setting an input pin will be ignored\n", bitstr, on);
else printf("set(%s = %d) success\n", bitstr, on);
return 0;
}
int do_get(int fd, const char * bitstr, int bit, int quiet)
{
int result;
if (ioctl(fd, TIOCMGET, &result)) {
fprintf(stderr, "get(%s) failed: %d %s\n", bitstr, errno, strerror(errno));
return 1;
}
if (quiet) printf("%d", (result & bit) ? 1 : 0);
else printf("%s = %d (%02x & %02x)\n", bitstr, (result & bit) ? 1 : 0, result, bit);
return 0;
}
int getbit(const char * str)
{
if (strcasecmp(str, "le") == 0) return TIOCM_LE;
if (strcasecmp(str, "rts") == 0) return TIOCM_RTS;
if (strcasecmp(str, "dtr") == 0) return TIOCM_DTR;
if (strcasecmp(str, "st") == 0) return TIOCM_ST;
if (strcasecmp(str, "sr") == 0) return TIOCM_SR;
if (strcasecmp(str, "cts") == 0) return TIOCM_CTS;
if (strcasecmp(str, "car") == 0) return TIOCM_CAR;
if (strcasecmp(str, "cd") == 0) return TIOCM_CD;
if (strcasecmp(str, "rng") == 0) return TIOCM_RNG;
if (strcasecmp(str, "ri") == 0) return TIOCM_RI;
if (strcasecmp(str, "dsr") == 0) return TIOCM_DSR;
if (strcasecmp(str, "out1") == 0) return TIOCM_OUT1;
if (strcasecmp(str, "out2") == 0) return TIOCM_OUT2;
if (strcasecmp(str, "loop") == 0) return TIOCM_LOOP;
return 0;
}
int main(int argc, char ** argv)
{
if (argc != 3 && (argc != 4 || (argv[3][0] != '1' && argv[3][0] != '0' && strcmp(argv[3], "-q")))) {
fprintf(stderr, "usage: %s dev pin [ 0 | 1 ]\n"
" pin 0 turns off pin, pin 1 turns on pin\n"
" pin without any argument reads its current state\n"
" add -q when reading to only output the bit\n"
" le: line enable (input, usually wired to dsr)\n"
" dtr: data terminal ready (output, dsr on other side)\n"
" rts: request to send (output, rts on other side)\n"
" st: secondary TXD (output)\n"
" sr: secondary RXD (output)\n"
" cts: clear to send (input, rts on other side)\n"
" car or cd: carrier detect (input)\n"
" rng or ri: ring indicator (input)\n"
" dsr: data set ready (input, dtr on other side)\n"
" out1: (output)\n"
" out2: (output)\n"
" loop: set loopback mode (for testing)\n", argv[0]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "failed to open \"%s\": %d %s\n", argv[1], errno, strerror(errno));
return 1;
}
int r;
if (argc == 4 && argv[3][0] != '-') r = do_set(fd, argv[2], getbit(argv[2]), argv[3][0] == '1' ? 1 : 0);
else r = do_get(fd, argv[2], getbit(argv[2]), (argc == 4 && strcmp(argv[3], "-q") == 0));
close(fd);
return r;
}