Logo Search packages:      
Sourcecode: dahdi-tools version File versions  Download package

patlooptest.c

/*
 * Written by Mark Spencer <markster@digium.com>
 * Based on previous works, designs, and architectures conceived and
 * written by Jim Dixon <jim@lambdatel.com>.
 *
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
 * Copyright (C) 2001-2008 Digium, Inc.
 *
 * All rights reserved.
 *
 * Primary Author: Mark Spencer <markster@digium.com>
 * Radio Support by Jim Dixon <jim@lambdatel.com>
 */

/*
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2 as published by the
 * Free Software Foundation. See the LICENSE file included with
 * 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>
#include <errno.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#include <dahdi/user.h>
#include "dahdi_tools_version.h"

#define BLOCK_SIZE      2039

#define CONTEXT_SIZE    7
/* Prints a set of bytes in hex format */
static void print_packet(unsigned char *buf, int len)
{
      int x;
      printf("{ ");
      for (x=0;x<len;x++)
            printf("%02x ",buf[x]);
      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;
      int res, x;
      int i;
      struct dahdi_params tp;
      int bs = BLOCK_SIZE;
      int skipcount = 10;
      unsigned char c=0,c1=0;
      unsigned char inbuf[BLOCK_SIZE];
      unsigned char outbuf[BLOCK_SIZE];
      int setup=0;
      unsigned long bytes=0;
      int timeout=0;
      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;
            }
      }

      /* 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", device, strerror(errno));
            exit(1);
      }
      if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) {
            fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno));
            exit(1);
      }
      if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) {
            fprintf(stderr, "Unable to get channel parameters\n");
            exit(1);
      }
      ioctl(fd, DAHDI_GETEVENT);

      i = DAHDI_FLUSH_ALL;
      if (ioctl(fd,DAHDI_FLUSH,&i) == -1) {
            perror("DAHDI_FLUSH");
            exit(255);
      }

      /* 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++) {
                  outbuf[x] = c1++;
            }

            res = write(fd,outbuf,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 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) {
                        printf("Going for it...\n");
                  }
                  continue;
            }

            res = read(fd, inbuf, bs);
            if (res < bs) {
                  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++;
            }
            /* Test the packet read back for data pattern */
            loop_errorcount = 0;
            for (x = 0; x < bs; x++)  {
                  /* if error */
                  if (inbuf[x] != c) {
                        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;  /* 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){
                  printf("Timeout achieved Ending Program\n");
                  printf("Test ran %ld loops of %d bytes/loop with %ld errors\n", currentloop, bs, total_errorcount);
                  return total_errorcount;
            }
      }
      
}

Generated by  Doxygen 1.6.0   Back to index