summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Bailey <dbailey@digium.com>2010-06-03 20:56:44 +0000
committerDoug Bailey <dbailey@digium.com>2010-06-03 20:56:44 +0000
commitcd20a52a84410f9b608abfd943afb83137d202f5 (patch)
tree493d92f9af36dbc144f664984587171867f81af3
parent9c4fce1299517cbaeff377decfa0ea2ee389fcb1 (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
-rw-r--r--patlooptest.c207
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;
}
}