diff options
author | Doug Bailey <dbailey@digium.com> | 2010-06-03 20:56:44 +0000 |
---|---|---|
committer | Doug Bailey <dbailey@digium.com> | 2010-06-03 20:56:44 +0000 |
commit | cd20a52a84410f9b608abfd943afb83137d202f5 (patch) | |
tree | 493d92f9af36dbc144f664984587171867f81af3 /patlooptest.c | |
parent | 9c4fce1299517cbaeff377decfa0ea2ee389fcb1 (diff) |
Add enhanced command line parsing and add more options into how errors are flagged and
what is displayed.
Still runs with the old usage: patlooptest <dahdi device> [<timeout>]
git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/trunk@8746 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'patlooptest.c')
-rw-r--r-- | patlooptest.c | 207 |
1 files changed, 177 insertions, 30 deletions
diff --git a/patlooptest.c b/patlooptest.c index 85b939c..4be399c 100644 --- a/patlooptest.c +++ b/patlooptest.c @@ -25,6 +25,14 @@ * this program for more details. */ +/* + * This test sends a set of incrementing byte values out the specified + * dadhi device. The device is then read back and the read back characters + * are verified that they increment as well. + * If there is a break in the incrementing pattern, an error is flagged + * and the comparison starts at the last value read. + */ + #include <stdio.h> #include <fcntl.h> #include <string.h> @@ -38,9 +46,11 @@ #include <dahdi/user.h> #include "dahdi_tools_version.h" -#define BLOCK_SIZE 2039 +#define BLOCK_SIZE 2039 -void print_packet(unsigned char *buf, int len) +#define CONTEXT_SIZE 7 +/* Prints a set of bytes in hex format */ +static void print_packet(unsigned char *buf, int len) { int x; printf("{ "); @@ -49,6 +59,44 @@ void print_packet(unsigned char *buf, int len) printf("}\n"); } +/* Shows data immediately before and after the specified byte to provide context for an error */ +static void show_error_context(unsigned char *buf, int offset, int bufsize) +{ + int low; + int total = CONTEXT_SIZE; + + if (offset >= bufsize || 0 >= bufsize || 0 > offset ) { + return; + } + + low = offset - (CONTEXT_SIZE-1)/2; + if (0 > low) { + total += low; + low = 0; + } + if (low + total > bufsize) { + total = bufsize - low; + } + buf += low; + printf("Offset %d ", low); + print_packet(buf, total); + return; +} + +/* Shows how the program can be invoked */ +static void usage(const char * progname) +{ + printf("%s: Pattern loop test\n", progname); + printf("Usage: %s <dahdi device> [-t <secs>] [-r <count>] [-b <count>] [-vh?] \n", progname); + printf("\t-? - Print this usage summary\n"); + printf("\t-t <secs> - # of seconds for the test to run\n"); + printf("\t-r <count> - # of test loops to run before a summary is printed\n"); + printf("\t-s <count> - # of writes to skip before testing for results\n"); + printf("\t-v - Verbosity (repetitive v's add to the verbosity level e.g. -vvvv)\n"); + printf("\t-b <# buffer bytes> - # of bytes to display from buffers on each pass\n"); + printf("\n\t Also accepts old style usage:\n\t %s <device name> [<timeout in secs>]\n", progname); +} + int main(int argc, char *argv[]) { int fd; @@ -61,17 +109,73 @@ int main(int argc, char *argv[]) unsigned char inbuf[BLOCK_SIZE]; unsigned char outbuf[BLOCK_SIZE]; int setup=0; - int errors=0; - int bytes=0; + unsigned long bytes=0; int timeout=0; - time_t start_time=0; - if (argc < 2 || argc > 3 ) { - fprintf(stderr, "Usage: %s <DAHDI device> [timeout]\n",argv[0]); - exit(1); + int loop_errorcount; + int reportloops = 0; + int buff_disp = 0; + unsigned long currentloop = 0; + unsigned long total_errorcount = 0; + int verbose = 0; + char * device; + int opt; + int oldstyle_cmdline = 1; + + /* Parse the command line arguments */ + while((opt = getopt(argc, argv, "b:s:t:r:v?h")) != -1) { + switch(opt) { + case 'h': + case '?': + usage(argv[0]); + exit(1); + break; + case 'b': + buff_disp = strtoul(optarg, NULL, 10); + if (BLOCK_SIZE < buff_disp) { + buff_disp = BLOCK_SIZE; + } + oldstyle_cmdline = 0; + break; + case 'r': + reportloops = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 's': + skipcount = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 't': + timeout = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 'v': + verbose++; + oldstyle_cmdline = 0; + break; + } } - fd = open(argv[1], O_RDWR, 0600); + + /* If no device was specified */ + if(NULL == argv[optind]) { + printf("You need to supply a dahdi device to test\n"); + usage(argv[0]); + exit (1); + } + + /* Get the dahdi device name */ + if (argv[optind]) + device = argv[optind]; + + /* To maintain backward compatibility with previous versions process old style command line */ + if (oldstyle_cmdline && argc > optind +1) { + timeout = strtoul(argv[optind+1], NULL, 10); + } + + time_t start_time = 0; + + fd = open(device, O_RDWR, 0600); if (fd < 0) { - fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); + fprintf(stderr, "Unable to open %s: %s\n", device, strerror(errno)); exit(1); } if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { @@ -85,63 +189,106 @@ int main(int argc, char *argv[]) ioctl(fd, DAHDI_GETEVENT); i = DAHDI_FLUSH_ALL; - if (ioctl(fd,DAHDI_FLUSH,&i) == -1) - { + if (ioctl(fd,DAHDI_FLUSH,&i) == -1) { perror("DAHDI_FLUSH"); exit(255); - } - if(argc==3){ - timeout=atoi(argv[2]); - start_time=time(NULL); + } + + /* Mark time if program has a specified timeout */ + if(0 < timeout){ + start_time = time(NULL); printf("Using Timeout of %d Seconds\n",timeout); } + /* ********* MAIN TESTING LOOP ************ */ for(;;) { + /* Prep the data and write it out to dahdi device */ res = bs; - for (x=0;x<bs;x++) + for (x = 0; x < bs; x++) { outbuf[x] = c1++; + } res = write(fd,outbuf,bs); - if (res != bs) - { + if (res != bs) { printf("Res is %d: %s\n", res, strerror(errno)); ioctl(fd, DAHDI_GETEVENT, &x); printf("Event: %d\n", x); exit(1); } - if (skipcount) - { - if (skipcount > 1) read(fd,inbuf,bs); + /* If this is the start of the test then skip a number of packets before test results */ + if (skipcount) { + if (skipcount > 1) { + res = read(fd,inbuf,bs); + } skipcount--; - if (!skipcount) puts("Going for it..."); + if (!skipcount) { + printf("Going for it...\n"); + } continue; - } + } res = read(fd, inbuf, bs); if (res < bs) { - printf("Res is %d\n", res); + printf("read error: returned %d\n", res); exit(1); } + /* If first time through, set byte that is used to test further bytes */ if (!setup) { c = inbuf[0]; setup++; } - for (x=0;x<bs;x++) { + /* Test the packet read back for data pattern */ + loop_errorcount = 0; + for (x = 0; x < bs; x++) { + /* if error */ if (inbuf[x] != c) { - printf("(Error %d): Unexpected result, %d != %d, %d bytes since last error.\n", ++errors, inbuf[x],c, bytes); + total_errorcount++; + loop_errorcount++; + if (oldstyle_cmdline) { + printf("(Error %ld): Unexpected result, %d != %d, %ld bytes since last error.\n", total_errorcount, inbuf[x],c, bytes); + } else { + if (1 <= verbose) { + printf("Error %ld (loop %ld, offset %d, error %d): Unexpected result, Read: 0x%02x, Expected 0x%02x.\n", + total_errorcount, + currentloop, + x, + loop_errorcount, + inbuf[x], + c); + } + if (2 <= verbose) { + show_error_context(inbuf, x, bs); + } + } + /* Reset the expected data to what was just read. so test can resynch on skipped data */ c = inbuf[x]; - bytes=0; + bytes=0; /* Reset the count from the last encountered error */ } c++; bytes++; } + /* If the user wants to see some of each buffer transaction */ + if (0 < buff_disp) { + printf("Buffer Display %d (errors =%d)\nIN: ", buff_disp, loop_errorcount); + print_packet(inbuf, 64); + printf("OUT:"); + print_packet(outbuf, 64); + } + + currentloop++; + /* Update stats if the user has specified it */ + if (0 < reportloops && 0 == (currentloop % reportloops)) { + printf("Status on loop %lu: Total errors = %lu\n", currentloop, total_errorcount); + + } #if 0 printf("(%d) Wrote %d bytes\n", packets++, res); #endif - if(timeout && (time(NULL)-start_time)>timeout){ + if(timeout && (time(NULL)-start_time) > timeout){ printf("Timeout achieved Ending Program\n"); - return errors; + printf("Test ran %ld loops of %d bytes/loop with %ld errors\n", currentloop, bs, total_errorcount); + return total_errorcount; } } |