/* * txflow.c * * Test xon/xoff handshaking by stty'ing a port to a known state, * blasting a burst of characters to the port, and watching for (and * displaying) any characters coming back from the port. * * Peter Berger; 14 September 1998 */ #define VERSION "1.3" #define BUFFSIZE 256 #define USAGE "txflow [-n terminal] [softflow | softflow] [-version] [-s 1200|9600|19200|38400]\n" #include #include #include #include #include #include #include static int chan = -1; static pid_t listen_pid; void fail( char *mes ) { printf( "%s", mes ); close( chan ); exit( 1 ); } usage() { fail( USAGE ); } void writechar( int c ) { if( write( chan, &c, 1 ) != 1 ) fail( "write failed\n" ); } void testpat( void ) { int i, c; for( i=1; i<1000; ++i ) { for( c='A'; c<='Z'; ++c ) writechar( c ); writechar( ' ' ); } } void listen() { int i, count; char buf[BUFFSIZE]; while( 1 ) { count = read( chan, &buf, BUFFSIZE ); if( count < 0 ) fail( "listen read failed\n" ); for( i=0; i %xx>\n", isprint(buf[i])? buf[i] : '*', buf[i] ); } } } void init( int argc, char *argv[] ) { struct termios t; char c; static softflow = 0; static char *termname = "/dev/ttyD0"; static speed_t speed = B9600; while( --argc ) { ++argv; if( !strcasecmp( *argv, "-version" ) ) { printf( "Version %s\n", VERSION ); fail( "" ); } else if( !strcasecmp( *argv, "-n" ) ) { if( --argc > 0 ) { termname = *(++argv); } else { usage(); } } else if( !strcasecmp( *argv, "-s" ) ) { if( --argc > 0 ) { ++argv; if( !strcasecmp( *argv, "1200" ) ) speed = B1200; else if( !strcmp( *argv, "9600" ) ) speed = B9600; else if( !strcmp( *argv, "19200" ) ) speed = B19200; else if( !strcmp( *argv, "38400" ) ) speed = B38400; else { printf( "Unsupported baudrate: '%s'\n", *argv ); usage(); } } else { usage(); } } else if( !strcasecmp( *argv, "softflow" ) ) softflow = 1; else if( !strcasecmp( *argv, "-softflow" ) ) softflow = 0; else if( !strcasecmp( *argv, "-help" ) ) { printf( "txflow version %s\n", VERSION ); usage(); } else { printf( "Unknown argument: '%s'\n", *argv ); usage(); } } //printf( "termname:%s\n", termname ); //getchar(); if( (chan = open( termname, O_RDWR|O_NOCTTY)) == -1 ) { printf( "Cannot open terminal:'%s'\n", termname ); exit( 1 ); } if( tcgetattr(chan, &t) != 0 ) fail( "Cannot get attributes\n" ); t.c_iflag &= ~(BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | INLCR |IGNCR |ICRNL |IXOFF | IXON ); //t.c_iflag |= IGNBRK | IXOFF | IXON; if( softflow ) { printf( "Setting software flow control\n" ); t.c_iflag |= IGNBRK | IXON | IXOFF; } else { printf( "Setting NO software flow control\n" ); t.c_iflag |= IGNBRK; } t.c_oflag &= ~(OPOST); t.c_lflag &= ~( ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|NOFLSH|TOSTOP); t.c_cflag &= ( CSIZE|CSTOPB|HUPCL|PARENB); t.c_cflag |= CLOCAL|CREAD|CS8; if( cfsetispeed( &t, speed ) == -1 ) fail( "Cannot set input speed\n" ); if( cfsetospeed( &t, speed ) == -1 ) fail( "Cannot set output speed\n" ); if( tcflush( chan, TCIFLUSH ) == -1 ) fail( "Cannot flush\n" ); if( tcsetattr( chan, TCSANOW, &t ) == -1 ) fail( "Cannot set attributes\n" ); } int main( int argc, char *argv[] ) { init( argc, argv ); if( (listen_pid = fork()) == 0 ) listen(); printf( "About to call testpat\n" ); getchar(); testpat(); if( kill( listen_pid, SIGKILL ) != 0 ) fail( "Failed to kill listen process\n" ); close( chan ); }