From 333bfb618bf21fc3f7cca7411acf0f42fcdc4b57 Mon Sep 17 00:00:00 2001 From: Kevin Kirspel Date: Thu, 4 May 2017 08:28:00 -0400 Subject: Adding test cases for FREEBSD termios support through tty --- .../include/rtems/bsd/test/default-termios-init.h | 158 ++++ testsuite/termios/test_main.c | 856 +++++++++++++++++++++ testsuite/termios/test_termios_driver.c | 136 ++++ testsuite/termios/test_termios_driver.h | 32 + testsuite/termios/test_termios_utilities.c | 233 ++++++ testsuite/termios/test_termios_utilities.h | 33 + testsuite/termios01/test_main.c | 690 +++++++++++++++++ testsuite/termios02/test_main.c | 140 ++++ testsuite/termios03/test_main.c | 73 ++ testsuite/termios04/test_main.c | 69 ++ testsuite/termios05/test_main.c | 65 ++ testsuite/termios06/test_main.c | 492 ++++++++++++ 12 files changed, 2977 insertions(+) create mode 100644 testsuite/include/rtems/bsd/test/default-termios-init.h create mode 100644 testsuite/termios/test_main.c create mode 100644 testsuite/termios/test_termios_driver.c create mode 100644 testsuite/termios/test_termios_driver.h create mode 100644 testsuite/termios/test_termios_utilities.c create mode 100644 testsuite/termios/test_termios_utilities.h create mode 100644 testsuite/termios01/test_main.c create mode 100644 testsuite/termios02/test_main.c create mode 100644 testsuite/termios03/test_main.c create mode 100644 testsuite/termios04/test_main.c create mode 100644 testsuite/termios05/test_main.c create mode 100644 testsuite/termios06/test_main.c (limited to 'testsuite') diff --git a/testsuite/include/rtems/bsd/test/default-termios-init.h b/testsuite/include/rtems/bsd/test/default-termios-init.h new file mode 100644 index 00000000..16c7ad74 --- /dev/null +++ b/testsuite/include/rtems/bsd/test/default-termios-init.h @@ -0,0 +1,158 @@ +/* + * Shared Network Test Initialization File + */ + +#ifndef RTEMS_BSD_TEST_DEFAULT_INIT_H +#define RTEMS_BSD_TEST_DEFAULT_INIT_H + +#include +#include +#include +#include +#include +#include +#include + +static void default_set_self_prio( rtems_task_priority prio ) +{ + rtems_status_code sc; + + sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio); + assert(sc == RTEMS_SUCCESSFUL); +} + +static void default_on_exit( int exit_code, void *arg ) +{ + rtems_printer printer; + + rtems_print_printer_printf(&printer); + rtems_stack_checker_report_usage_with_plugin(&printer); + + if ( exit_code == 0 ) { + puts( "*** END OF TEST " TEST_NAME " ***" ); + } +} + +rtems_task Init( + rtems_task_argument ignored +) +{ + rtems_status_code sc; + + /* + * Default the syslog priority to 'debug' to aid developers. + */ + rtems_bsd_setlogpriority("debug"); + + puts( "*** " TEST_NAME " TEST ***" ); + + /* + * BSD must support the new "shared IRQ PIC implementation" at this point. + * BSPs must also provide rtems_interrupt_server_initialize() which + * just requires including irq-server.[ch] in their build. + */ + + on_exit( default_on_exit, NULL ); + +#ifdef DEFAULT_EARLY_INITIALIZATION + early_initialization(); +#endif + + /* Let other tasks run to complete background work */ + default_set_self_prio( RTEMS_MAXIMUM_PRIORITY - 2 ); + + rtems_bsd_initialize(); + + /* Let the callout timer allocate its resources */ + sc = rtems_task_wake_after( 2 ); + assert(sc == RTEMS_SUCCESSFUL); + + test_main(); + /* should not return */ + + assert( 0 ); +} + +/* + * Configure RTEMS. + */ +#define CONFIGURE_MICROSECONDS_PER_TICK 1000 + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK + +#define CONFIGURE_MAXIMUM_DRIVERS 32 + +#define CONFIGURE_FILESYSTEM_DOSFS + +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32 + +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_STACK_CHECKER_ENABLED + +#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024) +#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024) + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024) +#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT + +#define CONFIGURE_INIT + +#include + +/* + * Configure LIBBSD device. + */ + #include + +/* + * Configure RTEMS Shell. + */ +#define CONFIGURE_SHELL_COMMANDS_INIT + +#include + +#include + +#define CONFIGURE_SHELL_USER_COMMANDS \ + &bsp_interrupt_shell_command, \ + &rtems_shell_STTY_Command, \ + &rtems_shell_SYSCTL_Command + +#define CONFIGURE_SHELL_COMMAND_CPUUSE +#define CONFIGURE_SHELL_COMMAND_PERIODUSE +#define CONFIGURE_SHELL_COMMAND_STACKUSE +#define CONFIGURE_SHELL_COMMAND_PROFREPORT + +#define CONFIGURE_SHELL_COMMAND_CP +#define CONFIGURE_SHELL_COMMAND_PWD +#define CONFIGURE_SHELL_COMMAND_LS +#define CONFIGURE_SHELL_COMMAND_LN +#define CONFIGURE_SHELL_COMMAND_LSOF +#define CONFIGURE_SHELL_COMMAND_CHDIR +#define CONFIGURE_SHELL_COMMAND_CD +#define CONFIGURE_SHELL_COMMAND_MKDIR +#define CONFIGURE_SHELL_COMMAND_RMDIR +#define CONFIGURE_SHELL_COMMAND_CAT +#define CONFIGURE_SHELL_COMMAND_MV +#define CONFIGURE_SHELL_COMMAND_RM +#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO + +#define CONFIGURE_SHELL_COMMAND_BLKSTATS +#define CONFIGURE_SHELL_COMMAND_BLKSYNC +#define CONFIGURE_SHELL_COMMAND_MOUNT +#define CONFIGURE_SHELL_COMMAND_UNMOUNT + +#include + +#endif /* RTEMS_BSD_TEST_DEFAULT_INIT_H */ \ No newline at end of file diff --git a/testsuite/termios/test_main.c b/testsuite/termios/test_main.c new file mode 100644 index 00000000..90e33826 --- /dev/null +++ b/testsuite/termios/test_main.c @@ -0,0 +1,856 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "test_termios_driver.h" + +#define TEST_NAME "LIBBSD TERMIOS" + +/* forward declarations to avoid warnings */ +void print_32bits(unsigned long bits, unsigned char size, char * names[]); +void print_c_iflag(struct termios * tp); +void print_c_oflag(struct termios * tp); +void print_c_lflag(struct termios * tp); +void print_c_cflag(struct termios * tp); +void print_c_cc(struct termios * tp); +void print_baud(const char* name, speed_t spd); +void print_termios(struct termios *tp); +unsigned long get_baud_rate(void); +unsigned long get_parity(void); +unsigned long get_stop_bits(void); +unsigned long get_data_bits(void); +void change_line_settings(struct termios *tp); +void canonical_input(struct termios *tp); +void do_raw_input(int vmin, int vtime); +void usage(void); + +#if !defined(fileno) +int fileno( FILE *stream); /* beyond ANSI */ +#endif + +/* Some of the termios dumping code depends on bit positions! */ + +void print_32bits( unsigned long bits, unsigned char size, char * names[] ) +{ + unsigned char i; + + for( i = 0; i < size; i++ ) { + if( (bits >> i) & 0x1 ) + printf( "%s ", names[i] ); + } +} + + +void print_c_iflag( struct termios * tp ) +{ + char * c_iflag_bits [] = { + "IGNBRK", /* 0000001 */ + "BRKINT", /* 0000002 */ + "IGNPAR", /* 0000004 */ + "PARMRK", /* 0000010 */ + "INPCK", /* 0000020 */ + "ISTRIP", /* 0000040 */ + "INLCR", /* 0000100 */ + "IGNCR", /* 0000200 */ + "ICRNL", /* 0000400 */ + "IUCLC", /* 0001000 */ + "IXON", /* 0002000 */ + "IXANY", /* 0004000 */ + "IXOFF", /* 0010000 */ + "IMAXBEL", /* 0020000 */ + "unknown", /* 0040000 */ + "unknown", /* 0100000 */ + "unknown", /* 0200000 */ + "unknown", /* 0400000 */ + "unknown", /* 1000000 */ + "unknown", /* 2000000 */ + "unknown" /* 4000000 */ + }; + + printf( "c_iflag = 0x%08x\n\t", tp->c_iflag ); + print_32bits( tp->c_iflag, sizeof( c_iflag_bits )/sizeof( char * ), c_iflag_bits ); + printf( "\n" ); +} + + +void print_c_oflag( struct termios * tp ) +{ + printf( "c_oflag = 0x%08x\n\t", tp->c_oflag ); + + if( tp->c_oflag & OPOST ) + printf( "OPOST " ); + + if( tp->c_oflag & OLCUC ) + printf( "OLCUC " ); + + if( tp->c_oflag & ONLCR ) + printf( "ONLCR " ); + + if( tp->c_oflag & ONOEOT ) + printf( "ONOEOT " ); + + if( tp->c_oflag & OCRNL ) + printf( "OCRNL " ); + + if( tp->c_oflag & ONOCR ) + printf( "ONOCR " ); + + if( tp->c_oflag & ONLRET ) + printf( "ONLRET " ); + + if( tp->c_oflag & OFILL ) + printf( "OFILL " ); + + if( tp->c_oflag & OFDEL ) + printf( "OFDEL " ); + + switch( tp->c_oflag & NLDLY ) { + case NL0: + printf( "NL0 " ); + break; + + case NL1: + printf( "NL1 " ); + break; + } + + switch( tp->c_oflag & CRDLY ) { + case CR0: + printf( "CR0 " ); + break; + + case CR1: + printf( "CR1 " ); + break; + + case CR2: + printf( "CR2 " ); + break; + + case CR3: + printf( "CR3 " ); + break; + } + + switch( tp->c_oflag & TABDLY ) { + case TAB0: + printf( "TAB0 " ); + break; + + case TAB1: + printf( "TAB1 " ); + break; + + case TAB2: + printf( "TAB2 " ); + break; + + case TAB3: + printf( "TAB3 " ); + break; + } + + switch( tp->c_oflag & BSDLY ) { + case BS0: + printf( "BS0 " ); + break; + + case BS1: + printf( "BS1 " ); + break; + } + + switch( tp->c_oflag & VTDLY ) { + case VT0: + printf( "VT0 " ); + break; + + case VT1: + printf( "VT1 " ); + break; + } + + switch( tp->c_oflag & FFDLY ) { + case FF0: + printf( "FF0" ); + break; + + case FF1: + printf( "FF1" ); + break; + } + printf( "\n" ); +} + + +void print_c_lflag( struct termios * tp ) +{ + char * c_lflag_bits [] = { + "ECHOKE", /* 0x00000001 */ + "ECHOE", /* 0x00000002 */ + "ECHOK", /* 0x00000004 */ + "ECHO", /* 0x00000008 */ + "ECHONL", /* 0x00000010 */ + "ECHOPRT", /* 0x00000020 */ + "ECHOCTL", /* 0x00000040 */ + "ISIG", /* 0x00000080 */ + "ICANON", /* 0x00000100 */ + "ALTWERASE", /* 0x00000200 */ + "IEXTEN", /* 0x00000400 */ + "EXTPROC", /* 0x00000800 */ + "XCASE", /* 0x00001000 */ + "unknown", /* 0x00002000 */ + "unknown", /* 0x00004000 */ + "unknown", /* 0x00008000 */ + "unknown", /* 0x00010000 */ + "unknown", /* 0x00020000 */ + "unknown", /* 0x00040000 */ + "unknown", /* 0x00080000 */ + "unknown", /* 0x00100000 */ + "unknown", /* 0x00200000 */ + "TOSTOP", /* 0x00400000 */ + "FLUSHO", /* 0x00800000 */ + "unknown", /* 0x01000000 */ + "NOKERNINFO", /* 0x02000000 */ + "unknown", /* 0x04000000 */ + "unknown", /* 0x08000000 */ + "unknown", /* 0x10000000 */ + "PENDIN", /* 0x20000000 */ + "unknown", /* 0x40000000 */ + "NOFLSH", /* 0x80000000 */ + }; + + printf( "c_lflag = 0x%08x\n\t", tp->c_lflag ); + print_32bits( tp->c_lflag, sizeof( c_lflag_bits )/sizeof( char * ), c_lflag_bits ); + printf( "\n" ); +} + + +void print_c_cflag( struct termios * tp ) +{ + printf( "c_cflag = 0x%08x\n", tp->c_cflag ); + + switch( tp->c_cflag & CSIZE ) { + case CS5: + printf( "\tCSIZE =\tCS5\n" ); + break; + + case CS6: + printf( "\tCSIZE =\tCS6\n" ); + break; + + case CS7: + printf( "\tCSIZE =\tCS7\n" ); + break; + + case CS8: + printf( "\tCSIZE =\tCS8\n" ); + break; + } + + if( tp->c_cflag & CIGNORE ) + printf( "\tCIGNORE set: iqnore c_cflags enabled\n" ); + else + printf( "\tCIGNORE clear: iqnore c_cflags disabled\n" ); + + if( tp->c_cflag & CSTOPB ) + printf( "\tCSTOPB set: send 2 stop bits\n" ); + else + printf( "\tCSTOPB clear: send 1 stop bit\n" ); + + if( tp->c_cflag & PARENB ) + printf( "\tPARENB set: parity enabled\n" ); + else + printf( "\tPARENB clear: parity disabled\n" ); + + if( tp->c_cflag & PARODD ) + printf( "\tPARODD set: parity odd\n" ); + else + printf( "\tPARODD clear: parity even\n" ); + + if( tp->c_cflag & CREAD ) + printf( "\tCREAD set: receiver enabled\n" ); + else + printf( "\tCREAD clear: treceiver disabled\n" ); + + if( tp->c_cflag & HUPCL ) + printf( "\tHUPCL set: enabled\n" ); + else + printf( "\tHUPCL clear: disabled\n" ); + + if( tp->c_cflag & CLOCAL ) + printf( "\tCLOCAL set: ignore modem lines\n" ); + else + printf( "\tCLOCAL clear: don't ignore modem lines\n" ); + + if( tp->c_cflag & CCTS_OFLOW ) + printf( "\tCCTS_OFLOW: hardware CTS output flow control enabled\n" ); + else + printf( "\tCCTS_OFLOW: hardware CTS output flow control disabled\n" ); + + if( tp->c_cflag & CRTS_IFLOW ) + printf( "\tCRTS_IFLOW: hardware RTS input flow control enabled\n" ); + else + printf( "\tCRTS_IFLOW: hardware RTS input flow control disabled\n" ); + + if( tp->c_cflag & CRTSCTS ) + printf( "\tCRTSCTS: harware flow control enabled?\n" ); + else + printf( "\tCRTSCTS: hardware flow control disabled?\n" ); + + if( tp->c_cflag & CDSR_OFLOW ) + printf( "\tCDSR_OFLOW: hardware DSR output flow control enabled\n" ); + else + printf( "\tCDSR_OFLOW: hardware DSR output flow control disabled\n" ); + + if( tp->c_cflag & CDTR_IFLOW ) + printf( "\tCDTR_IFLOW: hardware DTR input flow control enabled\n" ); + else + printf( "\tCDTR_IFLOW: hardware DTR input flow control disabled\n" ); + + if( tp->c_cflag & CCAR_OFLOW ) + printf( "\tCCAR_OFLOW: hardware CD output flow control enabled\n" ); + else + printf( "\tCCAR_OFLOW: hardware CD output flow control disabled\n" ); +} + + +void print_c_cc( struct termios * tp ) +{ + size_t i; + char * cc_index_names [ /* NCCS */ ] = { + "[VEOF] ", /* 0 */ + "[VEOL] ", /* 1 */ + "[VEOL2] ", /* 2 */ + "[VERASE] ", /* 3 */ + "[VWERASE] ", /* 4 */ + "[VKILL] ", /* 5 */ + "[VREPRINT]", /* 6 */ + "[VERASE2] ", /* 7 */ + "[VINTR] ", /* 8 */ + "[VQUIT] ", /* 9 */ + "[VSUSP] ", /* 10 */ + "[VDSUSP] ", /* 11 */ + "[VSTART] ", /* 12 */ + "[VSTOP] ", /* 13 */ + "[VLNEXT] ", /* 14 */ + "[VDISCARD]", /* 15 */ + "[VMIN] ", /* 16 */ + "[VTIME] ", /* 17 */ + "[VSTATUS] ", /* 18 */ + "unknown ", /* 19 */ + }; + + for( i = 0; i < sizeof(cc_index_names)/sizeof(char*) ; i++ ) { + printf( "c_cc%s = 0x%08x\n", cc_index_names[i], tp->c_cc[i] ); + } +} + + +void print_baud( const char* name, speed_t spd ) +{ + switch( spd ) { + case B0: + printf( "%s = B0\n", name ); + break; + + case B50: + printf( "%s = B50\n", name ); + break; + + case B75: + printf( "%s = B75\n", name ); + break; + + case B110: + printf( "%s = B110\n", name ); + break; + + case B134: + printf( "%s = B134\n", name ); + break; + + case B150: + printf( "%s = B150\n", name ); + break; + + case B200: + printf( "%s = B200\n", name ); + break; + + case B300: + printf( "%s = B300\n", name ); + break; + + case B600: + printf( "%s = B600\n", name ); + break; + + case B1200: + printf( "%s = B1200\n", name ); + break; + + case B1800: + printf( "%s = B1800\n", name ); + break; + + case B2400: + printf( "%s = B2400\n", name ); + break; + + case B4800: + printf( "%s = B4800\n", name ); + break; + + case B9600: + printf( "%s = B9600\n", name ); + break; + + case B19200: + printf( "%s = B19200\n", name ); + break; + + case B38400: + printf( "%s = B38400\n", name ); + break; + + case B7200: + printf( "%s = B7200\n", name ); + break; + + case B14400: + printf( "%s = B14400\n", name ); + break; + + case B28800: + printf( "%s = B28800\n", name ); + break; + + case B57600: + printf( "%s = B57600\n", name ); + break; + + case B76800: + printf( "%s = B76800\n", name ); + break; + + case B115200: + printf( "%s = B115200\n", name ); + break; + + case B230400: + printf( "%s = B230400\n", name ); + break; + + case B460800: + printf( "%s = B460800\n", name ); + break; + + case B921600: + printf( "%s = B921600\n", name ); + break; + + default: + printf( "%s = unknown (0x%08x)\n", name, (unsigned int)spd ); + break; + } +} + + +void print_termios( struct termios *tp ) +{ + printf( "\nLooking at the current termios settings:\n\n" ); + print_c_iflag( tp ); + print_c_oflag( tp ); + print_c_cflag( tp ); + print_c_lflag( tp ); + print_c_cc( tp ); + print_baud( "c_ispeed", tp->c_ispeed ); + print_baud( "c_ospeed", tp->c_ospeed ); + printf( "\n" ); +} + + +unsigned long get_baud_rate(void) +{ + unsigned long baud_rate; + + while( 1 ) { + printf( "Enter the numerical value for the new baud rate.\n" ); + printf( "Choices are: 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800\n" ); + printf( "2400, 4800, 9600, 19200, 38400, 7200, 14400, 28800, 57600, 76800\n" ); + printf( "115200, 230400, 460800, 921600\n" ); + printf( "\nYour choice: " ); + scanf( "%lu", &baud_rate ); + printf( "\n" ); + switch( baud_rate ) { + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 7200: return B7200; + case 14400: return B14400; + case 28800: return B28800; + case 57600: return B57600; + case 76800: return B76800; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 921600: return B921600; + + default: + printf( "%lu is not a valid choice. Try again.\n\n", baud_rate ); + break; + } + } +} + + +unsigned long get_parity(void) +{ + int parity; + + while( 1 ) { + printf( "Enter the numerical value for the new parity\n" ); + printf( "Choices are: 0 for no parity, 1 for even parity, 2 for odd parity\n" ); + printf( "\nYour choice: " ); + scanf( "%d", &parity ); + printf( "\n" ); + switch( parity ) { + case 0: + return 0; + + case 1: + return PARENB; + + case 2: + return PARENB | PARODD; + + default: + printf( "%d is not a valid choice. Try again.\n\n", parity ); + break; + } + } +} + + +unsigned long get_stop_bits(void) +{ + int stop_bits; + + while( 1 ) { + printf( "Enter the numerical value for the new number of stop bits\n" ); + printf( "Choices are: 1 or 2\n" ); + printf( "\nYour choice: " ); + scanf( "%d", &stop_bits ); + printf( "\n" ); + switch( stop_bits ) { + case 1: + return 0; + + case 2: + return CSTOPB; + + default: + printf( "%d is not a valid choice. Try again.\n\n", stop_bits ); + break; + } + } +} + + +unsigned long get_data_bits(void) +{ + int data_bits; + + while( 1 ) { + printf( "Enter the numerical value for the new number of data bits\n" ); + printf( "Choices are: 5, 6, 7 or 8\n" ); + printf( "\nYour choice: " ); + scanf( "%d", &data_bits ); + printf( "\n" ); + switch( data_bits ) { + case 5: + return CS5; + + case 6: + return CS6; + + case 7: + return CS7; + + case 8: + return CS8; + + default: + printf( "%d is not a valid choice. Try again.\n\n", data_bits ); + break; + } + } +} + + +void change_line_settings( struct termios *tp ) +{ + unsigned long baud_rate, parity, stop_bits, data_bits, sleep_time; + + printf( "\nSetting line characteristics\n\n" ); + + baud_rate = get_baud_rate(); + parity = get_parity(); + stop_bits = get_stop_bits(); + data_bits = get_data_bits(); + + printf( "NOTE: You will not see output until you switch your terminal settings!\n" ); + printf( "WARNING: If you do not switch your terminal settings, your terminal may hang.\n" ); + printf( "Enter the number of seconds the test will wait for you to switch your terminal\n" ); + printf( "settings before it continues\n" ); + printf( "Sleep time (in seconds): " ); + scanf( "%lu", &sleep_time ); + printf( "\n" ); + printf( "Setting line to new termios settings in %lu seconds.\n", sleep_time ); + + sleep( sleep_time ); + + tp->c_cflag = CLOCAL | CREAD | parity | stop_bits | data_bits; + tp->c_ispeed = baud_rate; + tp->c_ospeed = baud_rate; + if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) { + perror( "change_line_settings(): tcsetattr() failed" ); + exit( 1 ); + } + printf( "Line settings set.\n" ); +} + + +void canonical_input( struct termios *tp ) +{ + char c; + bool first_time = true; + + printf( "\nTesting canonical input\n\n" ); + + printf( "Setting line to canonical input mode.\n" ); + tp->c_lflag = ISIG | ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL | IEXTEN; + tp->c_iflag = BRKINT | ICRNL | IXON | IMAXBEL; + if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) { + perror( "canonical_input(): tcsetattr() failed" ); + exit( 1 ); + } + + while ( ( c = getchar () ) != '\n'); + printf( "Testing getchar(). Type some text followed by carriage return\n" ); + printf( "Each character you entered will be echoed back to you\n\n" ); + while ( ( c = getchar () ) != '\n') { + if( first_time ) { + printf( "\nYou typed:\n"); + first_time = false; + } + printf( "%c", c ); + } + printf( "\n\nCanonical input test done.\n" ); +} + + +/* + * Test raw (ICANON=0) input + */ +void do_raw_input( int vmin, int vtime ) +{ + int i; + struct termios old, new; + rtems_interval ticksPerSecond, then, now; + unsigned int msec; + unsigned long count; + int nread; + unsigned char cbuf[100]; + + printf( "Raw input test with VMIN=%d VTIME=%d\n", vmin, vtime ); + + ticksPerSecond = rtems_clock_get_ticks_per_second(); + if ( tcgetattr( fileno ( stdin ), &old ) < 0 ) { + perror( "do_raw_input(): tcgetattr() failed" ); + return; + } + + new = old; + new.c_lflag &= ~( ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL ); + new.c_cc[VMIN] = vmin; + new.c_cc[VTIME] = vtime; + if( tcsetattr( fileno( stdin ), TCSADRAIN, &new ) < 0 ) { + perror ("do_raw_input(): tcsetattr() failed" ); + return; + } + + do { + then = rtems_clock_get_ticks_since_boot(); + count = 0; + for(;;) { + nread = read( fileno( stdin ), cbuf, sizeof cbuf ); + if( nread < 0 ) { + perror( "do_raw_input(): read() failed" ); + goto out; + } + count++; + if( nread != 0 ) + break; + } + now = rtems_clock_get_ticks_since_boot(); + msec = (now - then) * 1000 / ticksPerSecond; + printf( "Count:%-10lu Interval:%3u.%3.3d Char:", + count, msec / 1000, msec % 1000 ); + + for( i = 0 ; i < nread ; i++ ) + printf (" 0x%2.2x", cbuf[i]); + printf ("\n"); + + } while( cbuf[0] != 'q' ); + +out: + if( tcsetattr( fileno( stdin ), TCSADRAIN, &old) < 0 ) + perror("do_raw_input(): tcsetattr() failed: %s\n" ); +} + + +static void raw_input( struct termios *tp ) +{ + printf( "\nTesting raw input input\n\n" ); + printf( "Hit 'q' to terminate the test\n" ); + + do_raw_input( 0, 0 ); + do_raw_input( 0, 20 ); + do_raw_input( 5, 0 ); + do_raw_input( 5, 20 ); + + printf( "\nRaw input test done.\n" ); +} + + +void usage( void ) +{ + printf( "\nYou have the following choices:\n" ); + printf( " 1 - Reset the struct termios\n" ); + printf( " 2 - Look at the current termios setting\n" ); + printf( " 3 - Change the line characteristics\n" ); + printf( " 4 - Test canonical input\n" ); + printf( " 5 - Test raw input\n" ); + printf( " 9 - Exit\n" ); + printf( "Enter your choice (1 to 5 or 9, followed by a carriage return): " ); +} + +static void notification( int fd, int seconds_remaining, void *arg ) +{ + printf( + "Press any key to check the termios input capabilities (%is remaining)\n", + seconds_remaining + ); +} + +static void +test_main(void) +{ + rtems_status_code status = RTEMS_SUCCESSFUL; + bool quit = false; + char c; + struct termios orig_termios, test_termios; + + puts( "*** " TEST_NAME " TEST ***" ); + + test_termios_make_dev(); + + status = rtems_shell_wait_for_input( + STDIN_FILENO, + 20, + notification, + NULL + ); + if (status == RTEMS_SUCCESSFUL) { + if( tcgetattr( fileno( stdin ), &orig_termios ) < 0 ) { + perror( "tcgetattr() failed" ); + exit( 0 ); + } + + test_termios = orig_termios; + + usage(); + while(!quit) { + switch( c = getchar() ) { + case '1': + printf( "\nResetting the line to the original termios setting\n\n" ); + test_termios = orig_termios; + if( tcsetattr( fileno( stdin ), TCSADRAIN, &test_termios ) < 0 ) { + perror( "tcsetattr() failed" ); + exit( 1 ); + } + usage(); + break; + + case '2': + print_termios( &test_termios ); + usage(); + break; + + case '3': + change_line_settings( &test_termios ); + usage(); + break; + + case '4': + canonical_input( &test_termios ); + usage(); + break; + + case '5': + raw_input( &test_termios ); + usage(); + break; + + case '9': + quit = true; + break; + + case '\n': + break; + + default: + printf( "\n%c is not a valid choice. Try again\n\n", c ); + usage(); + break; + } + } + } + + status = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME, + false, true, NULL); + assert(status == RTEMS_SUCCESSFUL); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios/test_termios_driver.c b/testsuite/termios/test_termios_driver.c new file mode 100644 index 00000000..35637b99 --- /dev/null +++ b/testsuite/termios/test_termios_driver.c @@ -0,0 +1,136 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../termios/test_termios_driver.h" + +static tsw_open_t test_termios_open; +static tsw_close_t test_termios_close; +static tsw_ioctl_t test_termios_ioctl; +static tsw_modem_t test_termios_modem; +static tsw_param_t test_termios_param; +static tsw_outwakeup_t test_termios_outwakeup; +static tsw_inwakeup_t test_termios_inwakeup; +static tsw_free_t test_termios_free; + +static struct ttydevsw test_termios_class = { + .tsw_flags = TF_INITLOCK | TF_CALLOUT, + .tsw_open = test_termios_open, + .tsw_close = test_termios_close, + .tsw_outwakeup = test_termios_outwakeup, + .tsw_inwakeup = test_termios_inwakeup, + .tsw_ioctl = test_termios_ioctl, + .tsw_param = test_termios_param, + .tsw_modem = test_termios_modem, + .tsw_free = test_termios_free, +}; + +struct test_termios_softc tt_softc; + +static int +test_termios_open(struct tty *tp) +{ + return (0); +} + +static void +test_termios_close(struct tty *tp) +{ +} + +static void +test_termios_outwakeup(struct tty *tp) +{ +} + +static void +test_termios_inwakeup(struct tty *tp) +{ +} + +static int +test_termios_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) +{ + return (ENOIOCTL); +} + +static int +test_termios_param(struct tty *tp, struct termios *t) +{ + return (0); +} + +static int +test_termios_modem(struct tty *tp, int sigon, int sigoff) +{ + struct test_termios_softc *sc = tty_softc(tp); + + if ((sigon == 0) && (sigoff == 0)) { + if (sc->sc_mcr & SER_DTR) { + sigon |= SER_DTR; + } + if (sc->sc_mcr & SER_RTS) { + sigon |= SER_RTS; + } + if (sc->sc_msr & SER_CTS) { + sigon |= SER_CTS; + } + if (sc->sc_msr & SER_DCD) { + sigon |= SER_DCD; + } + if (sc->sc_msr & SER_DSR) { + sigon |= SER_DSR; + } + if (sc->sc_msr & SER_RI) { + sigon |= SER_RI; + } + return (sigon); + } + if (sigon & SER_DTR) { + sc->sc_mcr |= SER_DTR; + } + if (sigoff & SER_DTR) { + sc->sc_mcr &= ~SER_DTR; + } + if (sigon & SER_RTS) { + sc->sc_mcr |= SER_RTS; + } + if (sigoff & SER_RTS) { + sc->sc_mcr &= ~SER_RTS; + } + return (0); +} + +static void +test_termios_free(void *xsc) +{ +} + +void +test_termios_make_dev(void) +{ + struct tty *tp = NULL; + + memset( &tt_softc, 0, sizeof( tt_softc )); + tt_softc.sc_msr = SER_DCD | SER_CTS | SER_DSR; + + tp = tty_alloc_mutex(&test_termios_class, &tt_softc, NULL); + assert(tp != NULL); + tt_softc.tp = tp; + + tty_makedev( tp, NULL, "%s", TERMIOS_TEST_DRIVER_TTY_PREFIX TERMIOS_TEST_DRIVER_TTY_UNIT); + assert(tp != NULL); +} \ No newline at end of file diff --git a/testsuite/termios/test_termios_driver.h b/testsuite/termios/test_termios_driver.h new file mode 100644 index 00000000..b8cf0b91 --- /dev/null +++ b/testsuite/termios/test_termios_driver.h @@ -0,0 +1,32 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef TEST_TERMIOS_DRIVER_H +#define TEST_TERMIOS_DRIVER_H + +/** + * This macro defines the standard name for the USB serial device + * that is available to applications. + */ +#define TERMIOS_TEST_DRIVER_TTY_PREFIX "T" +#define TERMIOS_TEST_DRIVER_TTY_UNIT "0" +#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/tty" TERMIOS_TEST_DRIVER_TTY_PREFIX TERMIOS_TEST_DRIVER_TTY_UNIT + +struct test_termios_softc { + uint8_t sc_lsr; + uint8_t sc_msr; + uint8_t sc_mcr; + struct tty *tp; +}; + +extern void test_termios_make_dev(void); + +extern struct test_termios_softc tt_softc; + +#endif /* TEST_TERMIOS_DRIVER_H */ \ No newline at end of file diff --git a/testsuite/termios/test_termios_utilities.c b/testsuite/termios/test_termios_utilities.c new file mode 100644 index 00000000..e8caf812 --- /dev/null +++ b/testsuite/termios/test_termios_utilities.c @@ -0,0 +1,233 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +int Test_fd; +uint8_t read_helper_buffer[256]; +uint8_t Tx_Buffer[TX_MAX]; + +void open_it(void) +{ + puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " ); + Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert( Test_fd != -1 ); + + change_iflag("BRKINT|ICRNL|IXON|IMAXBEL", 0xFFFFFFFF, BRKINT|ICRNL|IXON|IMAXBEL); + change_lflag("ISIG|ICANON|IEXTEN|ECHO|ECHOK|ECHOE|ECHOCTL", 0xFFFFFFFF, ISIG|ICANON|IEXTEN|ECHO|ECHOK|ECHOE|ECHOCTL); + change_oflag("OPOST|ONLCR|XTABS", 0xFFFFFFFF, OPOST|ONLCR|XTABS); +} + +void close_it(void) +{ + int rc; + + puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " ); + rc = close( Test_fd ); + assert( rc == 0 ); +} + +void read_it( ssize_t expected ) +{ + ssize_t rc; + char buf[32]; + + assert( expected <= sizeof(buf) ); + + printf( "read - %zd expected\n", expected ); + rc = read( Test_fd, buf, expected ); + if ( expected != rc ) + printf( "ERROR - expected=%zd rc=%zd\n", expected, rc ); + assert( expected == rc ); +} + +void write_it(void) +{ + ssize_t sc; + char ch[10] = "PPPD TEST"; + + puts( "write(PPPD TEST) - OK " ); + sc = write(Test_fd, ch, sizeof(ch)); + assert( sc == sizeof(ch) ); +} + +void change_iflag( const char *desc, int mask, int new ) +{ + int rc; + struct termios attr; + + printf( "Changing c_iflag to: %s\n", desc ); + rc = tcgetattr( Test_fd, &attr ); + assert( rc == 0 ); + + attr.c_iflag &= ~mask; + attr.c_iflag |= new; + + rc = tcsetattr( Test_fd, TCSANOW, &attr ); + assert( rc == 0 ); +} + +void change_lflag( const char *desc, int mask, int new ) +{ + int rc; + struct termios attr; + + printf( "Changing c_lflag to: %s\n", desc ); + rc = tcgetattr( Test_fd, &attr ); + assert( rc == 0 ); + + attr.c_lflag &= ~mask; + attr.c_lflag |= new; + + rc = tcsetattr( Test_fd, TCSANOW, &attr ); + assert( rc == 0 ); +} + +void change_oflag( const char *desc, int mask, int new ) +{ + int rc; + struct termios attr; + + printf( "Changing c_oflag to: %s\n", desc ); + rc = tcgetattr( Test_fd, &attr ); + assert( rc == 0 ); + + attr.c_oflag &= ~mask; + attr.c_oflag |= new; + + rc = tcsetattr( Test_fd, TCSANOW, &attr ); + assert( rc == 0 ); +} + +void change_vmin_vtime( const char *desc, int min, int time ) +{ + int rc; + struct termios attr; + + printf( "Changing %s - VMIN=%d VTIME=%d\n", desc, min, time ); + rc = tcgetattr( Test_fd, &attr ); + assert( rc == 0 ); + + attr.c_cc[VMIN] = min; + attr.c_cc[VTIME] = time; + + rc = tcsetattr( Test_fd, TCSANOW, &attr ); + assert( rc == 0 ); +} + +void enable_non_blocking(bool enable) +{ + int flags; + int rv; + + flags = fcntl(Test_fd, F_GETFL, 0); + assert(flags >= 0); + + if (enable) { + flags |= O_NONBLOCK; + } else { + flags &= ~O_NONBLOCK; + } + + rv = fcntl(Test_fd, F_SETFL, flags); + assert(rv == 0); +} + +void write_helper( int fd, const char *c ) +{ + size_t len; + int rc; + + len = strlen( c ); + printf( "Writing: %s", c ); + + rc = write( fd, c, len ); + assert( rc == len ); + + termios_test_driver_dump_tx("Transmitted"); +} + +void read_helper( int fd, const char *expected ) +{ + int rc; + size_t len; + + len = strlen( expected ); + + termios_test_driver_set_rx( expected, len ); + printf( "\nReading (expected):\n" ); + rtems_print_buffer( (unsigned char *)expected, len-1 ); + + rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) ); + assert( rc != -1 ); + + printf( "Read %d bytes from read(2)\n", rc ); + rtems_print_buffer( read_helper_buffer, rc ); + + termios_test_driver_dump_tx("Echoed"); +} + +int termios_test_driver_read_tx(void) +{ + int Tx_Index = 0; + int Tx_Size = TX_MAX; + int Tx_Length; + + for (;;) { + Tx_Length = ttydisc_getc(tt_softc.tp, &Tx_Buffer[Tx_Index], Tx_Size); + if (Tx_Length == 0) + break; + Tx_Index += Tx_Length; + Tx_Size -= Tx_Length; + } + + return Tx_Index; +} + +void termios_test_driver_dump_tx(const char *c) +{ + int Tx_Index; + + Tx_Index = termios_test_driver_read_tx(); + printf( "%s %d characters\n", c, Tx_Index ); + if( Tx_Index > 0 ) { + rtems_print_buffer( &Tx_Buffer[0], Tx_Index ); + } +} + +void termios_test_driver_set_rx( const void *p, size_t len ) +{ + tcflush(Test_fd, TCIFLUSH ); + ttydisc_rint_simple(tt_softc.tp, p, len); + ttydisc_rint_done(tt_softc.tp); +} + +void termios_test_driver_set_rx_char( char ch ) +{ + char chs[1]; + + chs[0] = ch; + termios_test_driver_set_rx( &chs[0], 1 ); +} \ No newline at end of file diff --git a/testsuite/termios/test_termios_utilities.h b/testsuite/termios/test_termios_utilities.h new file mode 100644 index 00000000..c655c6f9 --- /dev/null +++ b/testsuite/termios/test_termios_utilities.h @@ -0,0 +1,33 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef TEST_TERMIOS_UTILITIES_H +#define TEST_TERMIOS_UTILITIES_H + +#define TX_MAX 1024 + +extern void open_it(void); +extern void close_it(void); +extern void change_iflag(const char *desc, int mask, int new); +extern void change_lflag(const char *desc, int mask, int new); +extern void change_oflag(const char *desc, int mask, int new); +extern void change_vmin_vtime( const char *desc, int min, int time ); +extern void enable_non_blocking(bool enable); +extern void write_helper(int fd, const char *c); +extern void read_helper(int fd, const char *expected); +extern void termios_test_driver_dump_tx(const char *c); +extern int termios_test_driver_read_tx(void); +extern void termios_test_driver_set_rx( const void *p, size_t len ); +extern void termios_test_driver_set_rx_char( char ch ); + +extern int Test_fd; +extern uint8_t read_helper_buffer[256]; +extern uint8_t Tx_Buffer[TX_MAX]; + +#endif /* TEST_TERMIOS_UTILITIES_H */ \ No newline at end of file diff --git a/testsuite/termios01/test_main.c b/testsuite/termios01/test_main.c new file mode 100644 index 00000000..0ed991d1 --- /dev/null +++ b/testsuite/termios01/test_main.c @@ -0,0 +1,690 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define TTYDEFCHARS +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" + +#define TEST_NAME "LIBBSD TERMIOS 1" + +/* rtems_termios_baud_t is a typedefs to int32_t */ +#define PRIdrtems_termios_baud_t PRId32 + +/* + * Baud Rate Constant Mapping Entry + */ +typedef struct { + tcflag_t constant; + rtems_termios_baud_t baud; +} termios_baud_test_r; + +#define INVALID_CONSTANT ((tcflag_t) -2) + +#define INVALID_BAUD ((rtems_termios_baud_t) -2) +/* + * Baud Rate Constant Mapping Table + */ +static const termios_baud_test_r baud_table[] = { + { B0, 0 }, + { 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 }, + { B7200, 7200 }, + { B14400, 14400 }, + { B28800, 28800 }, + { B57600, 57600 }, + { B76800, 76800 }, + { B115200, 115200 }, + { B230400, 230400 }, + { B460800, 460800 }, + { B921600, 921600 }, + { INVALID_CONSTANT, INVALID_BAUD } +}; + +/* + * Character Size Constant Mapping Entry + */ +typedef struct { + tcflag_t constant; + int bits; +} termios_character_size_test_r; + +/* + * Character Size Constant Mapping Table + */ +static const termios_character_size_test_r char_size_table[] = { + { CS5, 5 }, + { CS6, 6 }, + { CS7, 7 }, + { CS8, 8 }, + { INVALID_CONSTANT, -1 } +}; + +/* + * Parity Constant Mapping Entry + */ +typedef struct { + tcflag_t constant; + const char *parity; +} termios_parity_test_r; + +/* + * Parity Constant Mapping Table + */ +static const termios_parity_test_r parity_table[] = { + { 0, "none" }, + { PARENB, "even" }, + { PARENB | PARODD, "odd" }, + { INVALID_CONSTANT, NULL } +}; + +/* + * Stop Bit Constant Mapping Entry + */ +typedef struct { + tcflag_t constant; + int stop; +} termios_stop_bits_test_r; + +/* + * Stop Bit Constant Mapping Table + */ +static const termios_stop_bits_test_r stop_bits_table[] = { + { 0, 1 }, + { CSTOPB, 2 }, + { INVALID_CONSTANT, -1 } +}; + +/* + * Test converting baud rate into an index + */ +static void test_termios_baud2index(void) +{ + int i; + int index; + + puts( "Test termios_baud2index..." ); + puts( "termios_baud_to_index(-2) - NOT OK" ); + i = rtems_termios_baud_to_index( INVALID_CONSTANT ); + assert( i == -1 ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + printf( + "termios_baud_to_index(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + index = rtems_termios_baud_to_index( baud_table[i].constant ); + assert(index == i); + } +} + +/* + * Test converting termios baud constant to baud number + */ +static void test_termios_baud2number(void) +{ + int i; + rtems_termios_baud_t number; + + puts( + "\n" + "Test termios_baud2number..." + ); + puts( "termios_baud_to_number(-2) - NOT OK" ); + number = rtems_termios_baud_to_number( INVALID_CONSTANT ); + assert( number == 0 ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + printf( + "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + number = rtems_termios_baud_to_number( baud_table[i].constant ); + assert( number == baud_table[i].baud ); + } +} + +/* + * Test converting baud number to termios baud constant + */ +static void test_termios_number_to_baud(void) +{ + int i; + tcflag_t termios_baud; + + puts( + "\n" + "Test termios_number_to_baud..." + ); + puts( "termios_number_to_baud(-2) - NOT OK" ); + termios_baud = rtems_termios_number_to_baud( INVALID_BAUD ); + assert( termios_baud == 0 ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + printf( + "termios_number_to_baud(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + termios_baud = rtems_termios_number_to_baud( baud_table[i].baud ); + assert( termios_baud == baud_table[i].constant ); + } +} + +/* + * Test all the baud rate options + */ +static void test_termios_set_baud( + int test +) +{ + int sc; + int i; + struct termios attr; + + puts( "Test termios setting device baud rate..." ); + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + sc = tcgetattr( test, &attr ); + assert(sc == 0); + + attr.c_ispeed = baud_table[i].constant; + attr.c_ospeed = baud_table[i].constant; + + printf( + "tcsetattr(TCSANOW, B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + sc = tcsetattr( test, TCSANOW, &attr ); + assert(sc == 0); + + printf( + "tcsetattr(TCSADRAIN, B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + sc = tcsetattr( test, TCSANOW, &attr ); + assert(sc == 0); + + printf( + "tcsetattr(TCSAFLUSH, B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + sc = tcsetattr( test, TCSAFLUSH, &attr ); + assert(sc == 0); + } +} + +/* + * Test all the character size options + */ +static void test_termios_set_charsize( + int test +) +{ + int sc; + int i; + struct termios attr; + + puts( + "\n" + "Test termios setting device character size ..." + ); + for (i=0 ; char_size_table[i].constant != INVALID_CONSTANT ; i++ ) { + tcflag_t csize = CSIZE; + + sc = tcgetattr( test, &attr ); + assert(sc == 0); + + attr.c_cflag &= ~csize; + attr.c_cflag |= char_size_table[i].constant; + + printf( "tcsetattr(TCSANOW, CS%d) - OK\n", char_size_table[i].bits ); + sc = tcsetattr( test, TCSANOW, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSADRAIN, CS%d) - OK\n", char_size_table[i].bits ); + sc = tcsetattr( test, TCSADRAIN, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSAFLUSH, CS%d) - OK\n", char_size_table[i].bits ); + sc = tcsetattr( test, TCSAFLUSH, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSASOFT, CS%d) - OK\n", char_size_table[i].bits ); + sc = tcsetattr( test, TCSASOFT, &attr ); + assert(sc == 0); + } +} + +/* + * Test all the parity options + */ +static void test_termios_set_parity( + int test +) +{ + int sc; + int i; + struct termios attr; + + puts( + "\n" + "Test termios setting device parity ..." + ); + for (i=0 ; parity_table[i].constant != INVALID_CONSTANT ; i++ ) { + tcflag_t par = PARENB | PARODD; + + sc = tcgetattr( test, &attr ); + assert(sc == 0); + + attr.c_cflag &= ~par; + attr.c_cflag |= parity_table[i].constant; + + printf( "tcsetattr(TCSANOW, %s) - OK\n", parity_table[i].parity ); + sc = tcsetattr( test, TCSANOW, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSADRAIN, %s) - OK\n", parity_table[i].parity ); + sc = tcsetattr( test, TCSADRAIN, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSAFLUSH, %s) - OK\n", parity_table[i].parity ); + sc = tcsetattr( test, TCSAFLUSH, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSASOFT, %s) - OK\n", parity_table[i].parity ); + sc = tcsetattr( test, TCSASOFT, &attr ); + assert(sc == 0); + } +} + +/* + * Test all the stop bit options + */ +static void test_termios_set_stop_bits( + int test +) +{ + int sc; + int i; + struct termios attr; + + puts( + "\n" + "Test termios setting device character size ..." + ); + for (i=0 ; stop_bits_table[i].constant != INVALID_CONSTANT ; i++ ) { + tcflag_t cstopb = CSTOPB; + + sc = tcgetattr( test, &attr ); + assert(sc == 0); + + attr.c_cflag &= ~cstopb; + attr.c_cflag |= stop_bits_table[i].constant; + + printf( "tcsetattr(TCSANOW, %d bit%s) - OK\n", + stop_bits_table[i].stop, + ((stop_bits_table[i].stop == 1) ? "" : "s") + ); + sc = tcsetattr( test, TCSANOW, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSADRAIN, %d bits) - OK\n", stop_bits_table[i].stop ); + sc = tcsetattr( test, TCSADRAIN, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSAFLUSH, %d bits) - OK\n", stop_bits_table[i].stop ); + sc = tcsetattr( test, TCSAFLUSH, &attr ); + assert(sc == 0); + + printf( "tcsetattr(TCSASOFT, %d bits) - OK\n", stop_bits_table[i].stop ); + sc = tcsetattr( test, TCSASOFT, &attr ); + assert(sc == 0); + } +} + +static void test_termios_cfoutspeed(void) +{ + int i; + int sc; + speed_t speed; + struct termios term; + speed_t bad; + + bad = B921600 << 1; + memset( &term, '\0', sizeof(term) ); + puts( "cfsetospeed(BAD BAUD) - EINVAL" ); + sc = cfsetospeed( &term, bad ); + assert( sc == -1 ); + assert( errno == EINVAL ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + memset( &term, '\0', sizeof(term) ); + printf( + "cfsetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + sc = cfsetospeed( &term, baud_table[i].constant ); + assert( !sc ); + printf( + "cfgetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + speed = cfgetospeed( &term ); + assert( speed == baud_table[i].constant ); + } +} + +static void test_termios_cfinspeed(void) +{ + int i; + int sc; + speed_t speed; + struct termios term; + speed_t bad; + + bad = B921600 << 1; + memset( &term, '\0', sizeof(term) ); + puts( "cfsetispeed(BAD BAUD) - EINVAL" ); + sc = cfsetispeed( &term, bad ); + assert( sc == -1 ); + assert( errno == EINVAL ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + memset( &term, '\0', sizeof(term) ); + printf( + "cfsetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + sc = cfsetispeed( &term, baud_table[i].constant ); + assert( !sc ); + + printf( + "cfgetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + speed = cfgetispeed( &term ); + assert( speed == baud_table[i].constant ); + } +} + +static void test_termios_cfsetspeed(void) +{ + int i; + int status; + speed_t speed; + struct termios term; + speed_t bad; + + bad = B921600 << 1; + memset( &term, '\0', sizeof(term) ); + puts( "cfsetspeed(BAD BAUD) - EINVAL" ); + status = cfsetspeed( &term, bad ); + assert( status == -1 ); + assert( errno == EINVAL ); + + for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) { + memset( &term, '\0', sizeof(term) ); + printf( + "cfsetspeed(B%" PRIdrtems_termios_baud_t ") - OK\n", + baud_table[i].baud + ); + status = cfsetspeed( &term, baud_table[i].constant ); + assert( !status ); + + printf( + "cfgetspeed(B%" PRIdrtems_termios_baud_t ") - checking both inspeed and outspeed - OK\n", + baud_table[i].baud + ); + speed = cfgetispeed( &term ); + assert( speed == baud_table[i].constant ); + + speed = cfgetospeed( &term ); + assert( speed == baud_table[i].constant ); + } +} + +static void test_termios_cfmakeraw(void) +{ + struct termios term; + + memset( &term, '\0', sizeof(term) ); + cfmakeraw( &term ); + puts( "cfmakeraw - OK" ); + + /* Check that all of the flags were set correctly */ + assert( ~(term.c_iflag & (IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)) ); + + assert( term.c_iflag & (IGNBRK) ); + + assert( ~(term.c_oflag & OPOST) ); + + assert( ~(term.c_lflag & (ECHO|ECHONL|ICANON|ISIG|IEXTEN)) ); + + assert( ~(term.c_cflag & (CSIZE|PARENB)) ); + + assert( term.c_cflag & (CS8|CREAD) ); + + assert( term.c_cc[VMIN] == 1 ); + + assert( term.c_cc[VTIME] == 0 ); +} + +static void test_termios_cfmakesane(void) +{ + struct termios term; + + memset( &term, '\0', sizeof(term) ); + cfmakesane( &term ); + puts( "cfmakesane - OK" ); + + /* Check that all of the flags were set correctly */ + assert( term.c_iflag == TTYDEF_IFLAG ); + + assert( term.c_oflag == TTYDEF_OFLAG ); + + assert( term.c_lflag == TTYDEF_LFLAG ); + + assert( term.c_cflag == TTYDEF_CFLAG ); + + assert( term.c_ispeed == TTYDEF_SPEED ); + + assert( term.c_ospeed == TTYDEF_SPEED ); + + assert( memcmp(&term.c_cc, ttydefchars, sizeof(term.c_cc)) == 0 ); +} + +static void test_set_best_baud(void) +{ + static const struct { + uint32_t baud; + speed_t speed; + } baud_to_speed_table[] = { + { 0, B0 }, + { 25, B0 }, + { 26, B50 }, + { 50, B50 }, + { 62, B50 }, + { 63, B75 }, + { 75, B75 }, + { 110, B110 }, + { 134, B134 }, + { 150, B150 }, + { 200, B200 }, + { 300, B300 }, + { 600, B600 }, + { 1200, B1200 }, + { 1800, B1800 }, + { 2400, B2400 }, + { 4800, B4800 }, + { 9600, B9600 }, + { 19200, B19200 }, + { 38400, B38400 }, + { 57600, B57600 }, + { 115200, B115200 }, + { 230400, B230400 }, + { 460800, B460800 }, + { 0xffffffff, B460800 } + }; + + size_t n = RTEMS_ARRAY_SIZE(baud_to_speed_table); + size_t i; + + for ( i = 0; i < n; ++i ) { + struct termios term; + + memset( &term, 0xff, sizeof( term ) ); + rtems_termios_set_best_baud( &term, baud_to_speed_table[ i ].baud ); + + assert( term.c_ispeed == baud_to_speed_table[ i ].speed ); + assert( term.c_ospeed == baud_to_speed_table[ i ].speed ); + } +} + +static void +test_main(void) +{ + int rc; + rtems_status_code sc; + rtems_device_major_number registered; + int test; + struct termios t; + int index = 0; + + /* + * Test baud rate + */ + test_termios_baud2index(); + test_termios_baud2number(); + test_termios_number_to_baud(); + + test_termios_make_dev(); + + puts( "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" ); + test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert(test != -1); + + /* + * tcsetattr - ERROR invalid operation + */ + puts( "tcsetattr - invalid operation - EINVAL" ); + rc = tcsetattr( test, INT_MAX, &t ); + assert(rc == -1); + assert(errno == EINVAL); + + test_termios_cfmakeraw(); + test_termios_cfmakesane(); + + /* + * tcsetattr - TCSADRAIN + */ + puts( "\ntcsetattr - drain - OK" ); + rc = tcsetattr( test, TCSADRAIN, &t ); + assert(rc == 0); + + test_termios_set_baud(test); + + puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" ); + rc = close( test ); + assert(rc == 0); + + /* + * Test character size + */ + puts( + "\n" + "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" + ); + test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert(test != -1); + + test_termios_set_charsize(test); + + puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" ); + rc = close( test ); + assert(rc == 0); + + /* + * Test parity + */ + puts( + "\n" + "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" + ); + test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert(test != -1); + + test_termios_set_parity(test); + + puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" ); + rc = close( test ); + assert(rc == 0); + + /* + * Test stop bits + */ + puts( + "\n" + "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" + ); + test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert(test != -1); + + test_termios_set_stop_bits(test); + + test_termios_cfoutspeed(); + + test_termios_cfinspeed(); + + test_termios_cfsetspeed(); + + puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" ); + rc = close( test ); + assert(rc == 0); + + puts( "Multiple open of the device" ); + for( ; index < 26; ++index ) { + test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR ); + assert(test != -1); + rc = close( test ); + assert(rc == 0); + } + puts( "" ); + + test_set_best_baud(); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios02/test_main.c b/testsuite/termios02/test_main.c new file mode 100644 index 00000000..3ec5c0b2 --- /dev/null +++ b/testsuite/termios02/test_main.c @@ -0,0 +1,140 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +#define TEST_NAME "LIBBSD TERMIOS 2" + +static void +test_main(void) +{ + int sc; + pid_t pid; + char *term_name_p; + char term_name[32]; + + test_termios_make_dev(); + + open_it(); + + puts( "tcdrain() - OK" ); + sc = tcdrain(Test_fd); + assert( !sc ); + + puts( "" ); + + /***** TEST TCFLOW *****/ + puts( "tcflow(TCOOFF) - ENOTSUP" ); + errno = 0; + sc = tcflow( Test_fd, TCOOFF ); + assert( sc == -1 ); + assert( errno == ENOTSUP ); + + puts( "tcflow(TCOON) - ENOTSUP" ); + errno = 0; + sc = tcflow( Test_fd, TCOON ); + assert( sc == -1 ); + assert( errno == ENOTSUP ); + + puts( "tcflow(TCIOFF) - ENOTSUP" ); + errno = 0; + sc = tcflow( Test_fd, TCIOFF ); + assert( sc == -1 ); + assert( errno == ENOTSUP ); + + puts( "tcflow(TCION) - ENOTSUP" ); + errno = 0; + sc = tcflow( Test_fd, TCION ); + assert( sc == -1 ); + assert( errno == ENOTSUP ); + + puts( "tcflow(22) - EINVAL" ); + errno = 0; + sc = tcflow( Test_fd, 22 ); + assert( sc == -1 ); + assert( errno == EINVAL ); + + puts( "" ); + + /***** TEST TCFLUSH *****/ + puts( "tcflush(TCIFLUSH) - OK" ); + errno = 0; + sc = tcflush( Test_fd, TCIFLUSH ); + assert( sc == 0 ); + assert( errno == 0 ); + + puts( "tcflush(TCOFLUSH) - OK" ); + sc = tcflush( Test_fd, TCOFLUSH ); + assert( sc == 0 ); + assert( errno == 0 ); + + puts( "tcflush(TCIOFLUSH) - OK" ); + sc = tcflush( Test_fd, TCIOFLUSH ); + assert( sc == 0 ); + assert( errno == 0 ); + + puts( "tcflush(22) - EINVAL" ); + errno = 0; + sc = tcflush( Test_fd, 22 ); + assert( sc == -1 ); + assert( errno == EINVAL ); + + puts( "" ); + + /***** TEST TCGETPGRP *****/ + puts( "tcgetpgrp() - OK" ); + pid = tcgetpgrp(Test_fd); + assert( pid == getpid() ); + + puts( "tcsetpgrp(3) - OK" ); + sc = tcsetpgrp( Test_fd, 3 ); + assert( !sc ); + + puts( "" ); + + /***** TEST TCSENDBREAK *****/ + puts( "tcsendbreak(0) - OK" ); + sc = tcsendbreak( Test_fd, 0 ); + assert( !sc ); + + puts( "" ); + + /***** TEST CTERMID *****/ + puts( "ctermid( NULL ) - OK" ); + term_name_p = ctermid( NULL ); + assert( term_name_p ); + printf( "ctermid ==> %s\n", term_name_p ); + + puts( "ctermid( term_name ) - OK" ); + term_name_p = ctermid( term_name ); + assert( term_name_p == term_name ); + printf( "ctermid ==> %s\n", term_name_p ); + + close_it(); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios03/test_main.c b/testsuite/termios03/test_main.c new file mode 100644 index 00000000..c92c4f0d --- /dev/null +++ b/testsuite/termios03/test_main.c @@ -0,0 +1,73 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +#define TEST_NAME "LIBBSD TERMIOS 3" + +const char ExpectedOutput_1[] = "This is test output.\n"; +const char ExpectedInput_1[] = "Test input this is.\n"; +const char ExpectedInput_2[] = "1235\b456.\n"; +const char ExpectedInput_3[] = "tab\ttab.\n"; +const char ExpectedInput_4[] = "cr\r."; +const char ExpectedInput_5[] = "aBcDeFgH.\n"; +const char ExpectedInput_6[] = "Testing VERASE\177.\n"; +const char ExpectedInput_7[] = "Testing VKILL\025.\n"; +const char ExpectedInput_8[] = "\177Testing VERASE in column 1.\n"; +const char ExpectedInput_9[] = "\t tab \tTesting VKILL after tab.\025\n"; + +static void +test_main(void) +{ + test_termios_make_dev(); + + open_it(); + + /* some basic cases */ + write_helper( Test_fd, ExpectedOutput_1 ); + read_helper( Test_fd, ExpectedInput_1 ); + read_helper( Test_fd, ExpectedInput_2 ); + read_helper( Test_fd, ExpectedInput_3 ); + read_helper( Test_fd, ExpectedInput_4 ); + + /* test to lower case input mapping */ + read_helper( Test_fd, ExpectedInput_5 ); + //IUCLC is not supported within FREEBSD so this should not change the output + change_iflag( "Enable to lower case mapping on input", IUCLC, IUCLC ); + read_helper( Test_fd, ExpectedInput_5 ); + change_iflag( "Disable to lower case mapping on input", IUCLC, 0 ); + + read_helper( Test_fd, ExpectedInput_6 ); + read_helper( Test_fd, ExpectedInput_7 ); + read_helper( Test_fd, ExpectedInput_8 ); + read_helper( Test_fd, ExpectedInput_9 ); + + puts( "" ); + close_it(); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios04/test_main.c b/testsuite/termios04/test_main.c new file mode 100644 index 00000000..f4d94767 --- /dev/null +++ b/testsuite/termios04/test_main.c @@ -0,0 +1,69 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +#define TEST_NAME "LIBBSD TERMIOS 4" + +const char XON_String[] = "\021"; +const char XOFF_String[] = "\023"; + +const char ExpectedOutput_1[] = +"0123456789012345678901234567890123456789" +"0123456789012345678901234567890123456789" +"0123456789012345678901234567890123456789" +"0123456789012345678901234567890123456789" +"0123456789012345678901234567890123456789\n"; + +static void +test_main(void) +{ + rtems_status_code sc; + + test_termios_make_dev(); + + open_it(); + + change_iflag( "Set XON/XOFF", IXON|IXOFF, IXON|IXOFF ); + + printf( "XOFF\n" ); + termios_test_driver_set_rx( XOFF_String, 1 ); + + write_helper( Test_fd, ExpectedOutput_1 ); + + sc = rtems_task_wake_after( 2 * rtems_clock_get_ticks_per_second() ); + assert( sc == RTEMS_SUCCESSFUL ); + + printf( "XON\n" ); + termios_test_driver_set_rx( XON_String, 1 ); + + termios_test_driver_dump_tx("Transmitted"); + + close_it(); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios05/test_main.c b/testsuite/termios05/test_main.c new file mode 100644 index 00000000..faad94fe --- /dev/null +++ b/testsuite/termios05/test_main.c @@ -0,0 +1,65 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +#define TEST_NAME "LIBBSD TERMIOS 5" + +static void +test_main(void) +{ + test_termios_make_dev(); + + open_it(); + + change_lflag( "non-canonical", ICANON, 0 ); + + change_vmin_vtime( "to polling", 0, 0 ); + read_it( 0 ); + + change_vmin_vtime( "to half-second timeout", 0, 5 ); + read_it( 0 ); + + change_vmin_vtime( "to half-second timeout", 5, 3 ); + puts( "Enqueue 2 characters" ); + termios_test_driver_set_rx( "ab", 2 ); + read_it( 2 ); + + change_vmin_vtime( "to half-second timeout", 5, 3 ); + puts( "Enqueue 1 character" ); + termios_test_driver_set_rx( "b", 1 ); + read_it( 1 ); + + puts( "Enqueue 7 characters" ); + termios_test_driver_set_rx( "1234567", 7 ); + read_it( 5 ); + read_it( 2 ); + + close_it(); + + exit(0); +} + +#include \ No newline at end of file diff --git a/testsuite/termios06/test_main.c b/testsuite/termios06/test_main.c new file mode 100644 index 00000000..dc6e3d6b --- /dev/null +++ b/testsuite/termios06/test_main.c @@ -0,0 +1,492 @@ +/* + * COPYRIGHT (c) 1989-2017. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../termios/test_termios_driver.h" +#include "../termios/test_termios_utilities.h" + +#define TEST_NAME "LIBBSD TERMIOS 6" + +static struct termios term; +static rtems_id flush_task_id; + +static void init_term(void) +{ + int rv; + + rv = tcgetattr(Test_fd, &term); + assert(rv == 0); + + term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP + | INLCR | IGNCR | ICRNL | IXON); + term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT + | ECHOCTL | ECHOKE | ICANON | ISIG | IEXTEN); + term.c_cflag &= ~(CSIZE | PARENB); + term.c_cflag |= CS8; + term.c_oflag &= ~(OPOST | ONLRET | ONLCR | OCRNL + | TABDLY | OLCUC); + + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 0; + + rv = tcsetattr(Test_fd, TCSANOW, &term); + assert(rv == 0); +} + +static void test_igncr(void) +{ + ssize_t n; + char c; + + c = 'x'; + + change_iflag("IGNCR", 0, IGNCR); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + termios_test_driver_set_rx_char('\r'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + change_iflag("~IGNCR", IGNCR, 0); + termios_test_driver_set_rx_char('\r'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\r'); +} + +static void test_istrip(void) +{ + ssize_t n; + char c; + + c = 'x'; + + change_iflag("ISTRIP", 0, ISTRIP); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + termios_test_driver_set_rx_char('\376'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '~'); + + change_iflag("~ISTRIP", ISTRIP, 0); + termios_test_driver_set_rx_char('\376'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\376'); +} + +static void test_iuclc(void) +{ + ssize_t n; + char c; + + c = 'x'; + + //IUCLC is not supported within FREEBSD so this should not change the output + change_iflag("IUCLC", 0, IUCLC); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + termios_test_driver_set_rx_char('A'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == 'A'); + + change_iflag("~IUCLC", IUCLC, 0); + termios_test_driver_set_rx_char('A'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == 'A'); +} + +static void test_icrnl(void) +{ + ssize_t n; + char c; + + c = 'x'; + + change_iflag("ICRNL", 0, ICRNL); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + termios_test_driver_set_rx_char('\r'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\n'); + + change_iflag("~ICRNL", ICRNL, 0); + termios_test_driver_set_rx_char('\r'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\r'); +} + +static void test_inlcr(void) +{ + ssize_t n; + char c; + + c = 'x'; + + change_iflag("INLCR", 0, INLCR); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 0); + assert(c == 'x'); + + termios_test_driver_set_rx_char('\n'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\r'); + + change_iflag("~INLCR", INLCR, 0); + termios_test_driver_set_rx_char('\n'); + + n = read(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(c == '\n'); +} + +static void test_onlret(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|ONLRET", 0, OPOST|ONLRET); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\n'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\n'); + + change_oflag("~(OPOST|ONLRET)", OPOST|ONLRET, 0); +} + +static void test_onlcr(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|ONLCR", 0, OPOST|ONLCR); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\n'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 2); + assert(Tx_Buffer[0] == '\r'); + assert(Tx_Buffer[1] == '\n'); + + change_oflag("~(OPOST|ONLCR)", OPOST|ONLCR, 0); +} + +static void test_onocr(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|ONOCR", 0, OPOST|ONOCR); + + c = '\r'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 0); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\r'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\r'); + + change_oflag("~(OPOST|ONOCR)", OPOST|ONOCR, 0); +} + +static void test_ocrnl(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|OCRNL", 0, OPOST|OCRNL); + + c = '\r'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\n'); + + change_oflag("~(OPOST|OCRNL)", OPOST|OCRNL, 0); +} + +static void test_ocrnl_onlret(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|OCRNL|ONLRET", 0, OPOST|OCRNL|ONLRET); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\r'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\n'); + + change_oflag("~(OPOST|OCRNL|ONLRET)", OPOST|OCRNL|ONLRET, 0); +} + +static void test_opost(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST", 0, OPOST); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\33'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\33'); + + c = '\t'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 8); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\t'); + + c = '\b'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 7); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\b'); + + c = '\r'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 0); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '\r'); + + change_oflag("~OPOST", OPOST, 0); +} + +static void test_xtabs(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + change_oflag("OPOST|XTABS", 0, OPOST|XTABS); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = '\t'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 8); + n = termios_test_driver_read_tx(); + assert(n == 7); + assert(Tx_Buffer[0] == ' '); + assert(Tx_Buffer[1] == ' '); + assert(Tx_Buffer[2] == ' '); + assert(Tx_Buffer[3] == ' '); + assert(Tx_Buffer[4] == ' '); + assert(Tx_Buffer[5] == ' '); + assert(Tx_Buffer[6] == ' '); + + change_oflag("~(OPOST|XTABS)", OPOST|XTABS, 0); +} + +static void test_olcuc(void) +{ + char c; + ssize_t n; + + tt_softc.tp->t_column = 0; + tcflush(Test_fd, TCOFLUSH); + + //OLCUC is not supported within FREEBSD so this should not change the output + change_oflag("OPOST|OLCUC", 0, OPOST|OLCUC); + + c = 'a'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 1); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'a'); + + c = 'B'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 2); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == 'B'); + + c = '9'; + n = write(Test_fd, &c, sizeof(c)); + assert(n == 1); + assert(tt_softc.tp->t_column == 3); + n = termios_test_driver_read_tx(); + assert(n == 1); + assert(Tx_Buffer[0] == '9'); + + change_oflag("~(OPOST|OLCUC)", OPOST|OLCUC, 0); +} + +static void +test_main(void) +{ + test_termios_make_dev(); + + open_it(); + + init_term(); + + test_igncr(); + test_istrip(); + test_iuclc(); + test_icrnl(); + test_inlcr(); + test_onlret(); + test_onlcr(); + test_onocr(); + test_ocrnl(); + test_ocrnl_onlret(); + test_opost(); + test_xtabs(); + test_olcuc(); + + close_it(); + + exit(0); +} + +#include \ No newline at end of file -- cgit v1.2.3