c7ecc129d7
ISDN4BSD is the work of our brand-new comitter: Hellmuth Michaelis, who has done a tremendous amount of work to bring us this far. There are still some outstanding issues and files to bring into the tree, and for now it will be needed to pick up all the extra docs from the isdn4bsd release. It is probably also a very good idea to subscribe to the isdn@freebsd.org mailing list before you try this out. These files correspond to release "beta Version 0.70.00 / December 1998" from Hellmuth.
739 lines
17 KiB
C
739 lines
17 KiB
C
/*
|
|
* Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*
|
|
* main.c - i4b selftest utility
|
|
* -----------------------------
|
|
*
|
|
* $Id: main.c,v 1.9 1998/12/05 18:04:06 hm Exp $
|
|
*
|
|
* last edit-date: [Sat Dec 5 18:18:17 1998]
|
|
*
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include <stdio.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <machine/i4b_ioctl.h>
|
|
#include <machine/i4b_cause.h>
|
|
|
|
static void kbdrdhdl ( void );
|
|
static void isdnrdhdl (int isdnfd );
|
|
|
|
void handle_connect_ind(unsigned char *ptr);
|
|
void handle_disconnect(unsigned char *ptr);
|
|
void handle_connect_active_ind(unsigned char *ptr);
|
|
|
|
int connect_response(int isdnfd, unsigned int cdid, int response);
|
|
int disconnect_request(int isdnfd, unsigned int cdid);
|
|
unsigned int get_cdid(int isdnfd);
|
|
int connect_request(int isdnfd, unsigned int cdid);
|
|
int do_test(void);
|
|
static void cleanup(void);
|
|
static void usage(void);
|
|
void setup_wrfix(int len, unsigned char *buf);
|
|
int check_rd(int len, unsigned char *wbuf, unsigned char *rdbuf);
|
|
|
|
static int isdnfd;
|
|
char outgoingnumber[32];
|
|
char incomingnumber[32];
|
|
int debug_level = 0;
|
|
|
|
#define I4BDEVICE "/dev/i4b"
|
|
#define DATADEV0 "/dev/i4brbch0"
|
|
#define DATAUNIT0 0
|
|
#define DATADEV1 "/dev/i4brbch1"
|
|
#define DATAUNIT1 1
|
|
|
|
unsigned int out_cdid = CDID_UNUSED;
|
|
unsigned int in_cdid = CDID_UNUSED;
|
|
|
|
int waitchar = 0;
|
|
int usehdlc = 0;
|
|
int controller = 0;
|
|
int dotest = 0;
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* program entry
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
int c;
|
|
fd_set set;
|
|
int ret;
|
|
char *ptr;
|
|
|
|
incomingnumber[0] = '\0';
|
|
outgoingnumber[0] = '\0';
|
|
|
|
while ((c = getopt(argc, argv, "c:d:hi:o:t:w?")) != EOF)
|
|
{
|
|
switch(c)
|
|
{
|
|
case 'c':
|
|
if(isdigit(*optarg))
|
|
{
|
|
controller = strtoul(optarg, NULL, 10);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: option -c requires a numeric argument!\n");
|
|
usage();
|
|
}
|
|
break;
|
|
|
|
case 'd':
|
|
if(isdigit(*optarg))
|
|
{
|
|
debug_level = strtoul(optarg, NULL, 10);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: option -d requires a numeric argument!\n");
|
|
usage();
|
|
}
|
|
break;
|
|
|
|
case 'o':
|
|
i = 0;
|
|
ptr = optarg;
|
|
|
|
while(*ptr)
|
|
{
|
|
if(isdigit(*ptr))
|
|
{
|
|
outgoingnumber[i++] = *ptr++;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: option -o requires a numeric argument!\n");
|
|
usage();
|
|
}
|
|
}
|
|
outgoingnumber[i] = '\0';
|
|
break;
|
|
|
|
case 'i':
|
|
i = 0;
|
|
ptr = optarg;
|
|
|
|
while(*ptr)
|
|
{
|
|
if(isdigit(*ptr))
|
|
{
|
|
incomingnumber[i++] = *ptr++;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: option -i requires a numeric argument!\n");
|
|
usage();
|
|
}
|
|
}
|
|
incomingnumber[i] = '\0';
|
|
break;
|
|
|
|
case 'w':
|
|
waitchar = 1;
|
|
break;
|
|
|
|
case 'h':
|
|
usehdlc = 1;
|
|
break;
|
|
|
|
case 't':
|
|
if(isdigit(*optarg))
|
|
{
|
|
dotest = strtoul(optarg, NULL, 10);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: option -t requires a numeric argument!\n");
|
|
usage();
|
|
}
|
|
break;
|
|
|
|
case '?':
|
|
default:
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if((strlen(incomingnumber) == 0) || (strlen(outgoingnumber) == 0))
|
|
usage();
|
|
|
|
fprintf(stderr, "isdntest: accepting calls from telephone number [%s] \n", incomingnumber);
|
|
fprintf(stderr, "isdntest: calling out telephone number [%s] \n", outgoingnumber);
|
|
|
|
if((atexit(cleanup)) != 0)
|
|
{
|
|
fprintf(stderr, "isdntest: atexit error: %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
/* open isdn device */
|
|
|
|
if((isdnfd = open(I4BDEVICE, O_RDWR)) < 0)
|
|
{
|
|
fprintf(stderr, "\nisdntest: cannot open %s: %s\n", I4BDEVICE, strerror(errno));
|
|
fprintf(stderr, " isdnd is probably running, to use isdntest,\n");
|
|
fprintf(stderr, " terminate isdnd and then run isdntest again!\n");
|
|
exit(1);
|
|
}
|
|
|
|
if((out_cdid = get_cdid(isdnfd)) == 0)
|
|
{
|
|
fprintf(stderr, "isdntest: error getting cdid: %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
if((connect_request(isdnfd, out_cdid)) == -1)
|
|
{
|
|
fprintf(stderr, "isdntest: error, outgoing call failed!\n");
|
|
exit(1);
|
|
}
|
|
|
|
for(;;)
|
|
{
|
|
FD_ZERO(&set);
|
|
|
|
FD_SET(0, &set);
|
|
|
|
FD_SET(isdnfd, &set);
|
|
|
|
ret = select(isdnfd + 1, &set, NULL, NULL, NULL);
|
|
|
|
if(ret > 0)
|
|
{
|
|
if(FD_ISSET(isdnfd, &set))
|
|
isdnrdhdl(isdnfd);
|
|
|
|
if(FD_ISSET(0, &set))
|
|
kbdrdhdl();
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest: select error: %s\n", strerror(errno));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* data from keyboard available
|
|
*---------------------------------------------------------------------------*/
|
|
static void
|
|
kbdrdhdl(void)
|
|
{
|
|
cleanup();
|
|
exit(2);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* data from /dev/isdn available, read and process them
|
|
*---------------------------------------------------------------------------*/
|
|
static void
|
|
isdnrdhdl(int isdnfd)
|
|
{
|
|
static unsigned char buf[1024];
|
|
int len;
|
|
|
|
if((len = read(isdnfd, buf, 1024 - 1)) > 0)
|
|
{
|
|
switch (buf[0])
|
|
{
|
|
case MSG_CONNECT_IND:
|
|
handle_connect_ind(&buf[0]);
|
|
break;
|
|
|
|
case MSG_CONNECT_ACTIVE_IND:
|
|
handle_connect_active_ind(&buf[0]);
|
|
break;
|
|
|
|
case MSG_DISCONNECT_IND:
|
|
handle_disconnect(&buf[0]);
|
|
break;
|
|
|
|
default:
|
|
if(debug_level)
|
|
fprintf(stderr, "isdntest: unknown message 0x%x = %c\n", buf[0], buf[0]);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest: read error, errno = %d, length = %d", errno, len);
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* usage display and exit
|
|
*---------------------------------------------------------------------------*/
|
|
static void
|
|
usage(void)
|
|
{
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "isdntest - i4b selftest, compiled %s %s\n",__DATE__, __TIME__);
|
|
fprintf(stderr, "usage: isdntest -c <ctrl> -h -i <telno> -o <telno>\n");
|
|
fprintf(stderr, " -c <ctrl> specify controller to use\n");
|
|
fprintf(stderr, " -h use HDLC as Bchannel protocol\n");
|
|
fprintf(stderr, " -i <telno> incoming telephone number\n");
|
|
fprintf(stderr, " -o <telno> outgoing telephone number\n");
|
|
fprintf(stderr, " -w wait for keyboard entry to disconnect\n");
|
|
fprintf(stderr, " -t num send test pattern num times\n");
|
|
fprintf(stderr, "\n");
|
|
exit(1);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* initiate an outgoing connection
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
connect_request(int isdnfd, unsigned int cdid)
|
|
{
|
|
msg_connect_req_t mcr;
|
|
int ret;
|
|
|
|
bzero(&mcr, sizeof(msg_connect_req_t));
|
|
|
|
mcr.controller = controller;
|
|
mcr.channel = CHAN_ANY; /* any channel */
|
|
mcr.cdid = cdid; /* cdid from get_cdid() */
|
|
|
|
if(usehdlc)
|
|
mcr.bprot = BPROT_RHDLC;/* b channel protocol */
|
|
else
|
|
mcr.bprot = BPROT_NONE; /* b channel protocol */
|
|
|
|
mcr.driver = BDRV_RBCH; /* raw b channel driver */
|
|
mcr.driver_unit = DATAUNIT0; /* raw b channel driver unit */
|
|
|
|
strcpy(mcr.dst_telno, outgoingnumber);
|
|
strcpy(mcr.src_telno, incomingnumber);
|
|
|
|
if((ret = ioctl(isdnfd, I4B_CONNECT_REQ, &mcr)) < 0)
|
|
{
|
|
fprintf(stderr, "ioctl I4B_CONNECT_REQ failed: %s", strerror(errno));
|
|
return(-1);
|
|
}
|
|
fprintf(stderr, "isdntest: calling out to telephone number [%s] \n", outgoingnumber);
|
|
return(0);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* handle setup indicator
|
|
*---------------------------------------------------------------------------*/
|
|
void
|
|
handle_connect_ind(unsigned char *ptr)
|
|
{
|
|
msg_connect_ind_t *msi = (msg_connect_ind_t *)ptr;
|
|
|
|
fprintf(stderr, "isdntest: incoming SETUP: from %s to %s\n",
|
|
msi->src_telno,
|
|
msi->dst_telno);
|
|
|
|
fprintf(stderr, " channel %d, controller %d, bprot %d, cdid %d\n",
|
|
msi->channel,
|
|
msi->controller,
|
|
msi->bprot,
|
|
msi->header.cdid);
|
|
|
|
in_cdid = msi->header.cdid;
|
|
|
|
if(strcmp(msi->dst_telno, outgoingnumber))
|
|
{
|
|
msg_connect_resp_t msr;
|
|
int ret;
|
|
|
|
fprintf(stderr, "isdntest: ignoring incoming SETUP: my number [%s] != outgoing [%s]\n",
|
|
msi->dst_telno, outgoingnumber);
|
|
|
|
msr.cdid = in_cdid;
|
|
msr.response = SETUP_RESP_DNTCRE;
|
|
|
|
if((ret = ioctl(isdnfd, I4B_CONNECT_RESP, &msr)) < 0)
|
|
{
|
|
fprintf(stderr, "ioctl I4B_CONNECT_RESP ignore failed: %s", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
msg_connect_resp_t msr;
|
|
int ret;
|
|
|
|
fprintf(stderr, "isdntest: accepting call, sending CONNECT_RESPONSE .....\n");
|
|
|
|
msr.cdid = in_cdid;
|
|
msr.response = SETUP_RESP_ACCEPT;
|
|
|
|
if(usehdlc)
|
|
msr.bprot = BPROT_RHDLC;
|
|
else
|
|
msr.bprot = BPROT_NONE;
|
|
|
|
msr.driver = BDRV_RBCH;
|
|
msr.driver_unit = DATAUNIT1;
|
|
|
|
if((ret = ioctl(isdnfd, I4B_CONNECT_RESP, &msr)) < 0)
|
|
{
|
|
fprintf(stderr, "ioctl I4B_CONNECT_RESP accept failed: %s", strerror(errno));
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
#define SLEEPTIME 5
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* handle connection active
|
|
*---------------------------------------------------------------------------*/
|
|
void
|
|
handle_connect_active_ind(unsigned char *ptr)
|
|
{
|
|
msg_connect_active_ind_t *msi = (msg_connect_active_ind_t *)ptr;
|
|
int i;
|
|
|
|
fprintf(stderr, "isdntest: connection active, cdid %d\n", msi->header.cdid);
|
|
|
|
if(out_cdid == msi->header.cdid)
|
|
{
|
|
if(waitchar)
|
|
{
|
|
fprintf(stderr, "isdntest: press any key to disconnect ...%c%c%c\n", 0x07, 0x07, 0x07);
|
|
getchar();
|
|
}
|
|
else
|
|
{
|
|
if(dotest)
|
|
{
|
|
do_test();
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest: %d secs delay until disconnect:", SLEEPTIME);
|
|
|
|
for(i=0; i < SLEEPTIME;i++)
|
|
{
|
|
fprintf(stderr, " .");
|
|
sleep(1);
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
cleanup();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* handle disconnect indication
|
|
*---------------------------------------------------------------------------*/
|
|
void
|
|
handle_disconnect(unsigned char *ptr)
|
|
{
|
|
msg_disconnect_ind_t *mdi = (msg_disconnect_ind_t *)ptr;
|
|
|
|
if(mdi->header.cdid == out_cdid)
|
|
{
|
|
fprintf(stderr, "isdntest: incoming disconnect indication, cdid %d (out_cdid), cause %d\n",
|
|
mdi->header.cdid, mdi->cause);
|
|
|
|
out_cdid = CDID_UNUSED;
|
|
}
|
|
else if(mdi->header.cdid == in_cdid)
|
|
{
|
|
fprintf(stderr, "isdntest: incoming disconnect indication, cdid %d (in_cdid), cause %d\n",
|
|
mdi->header.cdid, mdi->cause);
|
|
in_cdid = CDID_UNUSED;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest: incoming disconnect indication, cdid %d (???), cause %d\n",
|
|
mdi->header.cdid, mdi->cause);
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* hang up
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
disconnect_request(int isdnfd, unsigned int cdid)
|
|
{
|
|
msg_discon_req_t mdr;
|
|
int ret;
|
|
|
|
mdr.cdid = cdid;
|
|
mdr.cause = (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL;
|
|
|
|
if((ret = ioctl(isdnfd, I4B_DISCONNECT_REQ, &mdr)) < 0)
|
|
{
|
|
fprintf(stderr, "ioctl I4B_DISCONNECT_REQ failed: %s", strerror(errno));
|
|
return(-1);
|
|
}
|
|
fprintf(stderr, "isdntest: sending disconnect request\n");
|
|
return(0);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* get cdid from kernel
|
|
*---------------------------------------------------------------------------*/
|
|
unsigned int
|
|
get_cdid(int isdnfd)
|
|
{
|
|
msg_cdid_req_t mcr;
|
|
int ret;
|
|
|
|
mcr.cdid = 0;
|
|
|
|
if((ret = ioctl(isdnfd, I4B_CDID_REQ, &mcr)) < 0)
|
|
{
|
|
fprintf(stderr, "ioctl I4B_CDID_REQ failed: %s", strerror(errno));
|
|
return(0);
|
|
}
|
|
fprintf(stderr, "isdntest: got cdid %d from kernel\n", mcr.cdid);
|
|
return(mcr.cdid);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* make shure all cdid's are inactive before leaving
|
|
*---------------------------------------------------------------------------*/
|
|
void cleanup(void)
|
|
{
|
|
int len;
|
|
char buf[1024];
|
|
|
|
if(out_cdid != CDID_UNUSED)
|
|
{
|
|
fprintf(stderr, "isdntest: cleanup, send disconnect req for out_cdid %d, in_cdid %d\n", out_cdid, in_cdid);
|
|
disconnect_request(isdnfd, out_cdid);
|
|
}
|
|
|
|
while((out_cdid != CDID_UNUSED) || (in_cdid != CDID_UNUSED))
|
|
{
|
|
fprintf(stderr, "isdntest: cleanup, out_cdid %d, in_cdid %d\n", out_cdid, in_cdid);
|
|
|
|
if((len = read(isdnfd, buf, 1024 - 1)) > 0)
|
|
{
|
|
switch (buf[0])
|
|
{
|
|
case MSG_CONNECT_IND:
|
|
handle_connect_ind(&buf[0]);
|
|
break;
|
|
|
|
case MSG_CONNECT_ACTIVE_IND:
|
|
handle_connect_active_ind(&buf[0]);
|
|
break;
|
|
|
|
case MSG_DISCONNECT_IND:
|
|
handle_disconnect(&buf[0]);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "isdntest: unknown message 0x%x = %c\n", buf[0], buf[0]);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest: read error, errno = %d, length = %d", errno, len);
|
|
}
|
|
}
|
|
fprintf(stderr, "isdntest: exit cleanup, out_cdid %d, in_cdid %d\n", out_cdid, in_cdid);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* test the b-channels
|
|
*---------------------------------------------------------------------------*/
|
|
int do_test(void)
|
|
{
|
|
|
|
#define FPH 0x3c
|
|
#define FPL 0x66
|
|
|
|
int fd0, fd1;
|
|
unsigned char wrbuf[2048];
|
|
unsigned char rdbuf[2048];
|
|
int sz;
|
|
fd_set set;
|
|
struct timeval timeout;
|
|
int ret;
|
|
int frame;
|
|
int errcnt;
|
|
int frm_len;
|
|
int bytecnt = 0;
|
|
time_t start_time;
|
|
time_t cur_time;
|
|
time_t run_time;
|
|
|
|
if((fd0 = open(DATADEV0, O_RDWR)) == -1)
|
|
{
|
|
fprintf(stderr, "open of %s failed: %s", DATADEV0, strerror(errno));
|
|
return(-1);
|
|
}
|
|
|
|
if((fd1 = open(DATADEV1, O_RDWR)) == -1)
|
|
{
|
|
fprintf(stderr, "open of %s failed: %s", DATADEV1, strerror(errno));
|
|
return(-1);
|
|
}
|
|
|
|
printf("\n");
|
|
frame = 0;
|
|
errcnt = 0;
|
|
|
|
frm_len = 2;
|
|
|
|
start_time = time(NULL);
|
|
|
|
printf(" frame size errors totalbytes bps elapsedtime\n");
|
|
|
|
for(;dotest > 0; dotest--)
|
|
{
|
|
setup_wrfix(frm_len, &wrbuf[0]);
|
|
|
|
frame++;
|
|
|
|
bytecnt += frm_len;
|
|
|
|
printf("%6d %4d", frame, frm_len);
|
|
fflush(stdout);
|
|
|
|
if((sz = write(fd0, wrbuf, frm_len)) != frm_len)
|
|
{
|
|
fprintf(stderr, "write (%d of %d bytes) to %s failed: %s\n", sz, frm_len, DATADEV0, strerror(errno));
|
|
}
|
|
|
|
timeout.tv_sec = 2;
|
|
timeout.tv_usec = 0;
|
|
|
|
FD_ZERO(&set);
|
|
|
|
FD_SET(0, &set);
|
|
FD_SET(fd1, &set);
|
|
|
|
ret = select(fd1+1, &set, NULL, NULL, &timeout);
|
|
|
|
if(ret > 0)
|
|
{
|
|
if(FD_ISSET(fd1, &set))
|
|
{
|
|
if((sz = read(fd1, rdbuf, 2048)) != frm_len)
|
|
{
|
|
fprintf(stderr, "read (%d bytes) from %s failed: %s\n", sz, DATADEV1, strerror(errno));
|
|
}
|
|
|
|
cur_time = time(NULL);
|
|
run_time = difftime(cur_time, start_time);
|
|
|
|
if(run_time == 0)
|
|
run_time = 1;
|
|
|
|
printf(" %6d %10d %4d %2.2d:%2.2d:%2.2d \r",
|
|
errcnt, bytecnt,
|
|
(int)((int)bytecnt/(int)run_time),
|
|
(int)run_time/3600, (int)run_time/60, (int)run_time%60);
|
|
fflush(stdout);
|
|
|
|
errcnt += check_rd(frm_len, &wrbuf[0], &rdbuf[0]);
|
|
|
|
#ifdef NOTDEF
|
|
for(i=0; i<sz; i++)
|
|
{
|
|
printf("0x%02x ", (unsigned char)rdbuf[i]);
|
|
}
|
|
printf("\n");
|
|
#endif
|
|
}
|
|
|
|
if(FD_ISSET(0, &set))
|
|
{
|
|
return(0);
|
|
printf("\n\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "isdntest, do_test: select error: %s\n", strerror(errno));
|
|
}
|
|
|
|
frm_len = frm_len*2;
|
|
if(frm_len > 2048)
|
|
frm_len = 2;
|
|
|
|
}
|
|
printf("\n\n");
|
|
return(0);
|
|
}
|
|
|
|
void
|
|
setup_wrfix(int len, unsigned char *buf)
|
|
{
|
|
register int i;
|
|
|
|
for(i=0; i<len;)
|
|
{
|
|
*buf = FPH;
|
|
buf++;
|
|
*buf = FPL;
|
|
buf++;
|
|
i+=2;
|
|
}
|
|
}
|
|
|
|
int
|
|
check_rd(int len, unsigned char *wbuf, unsigned char *rbuf)
|
|
{
|
|
register int i;
|
|
int ret = 0;
|
|
|
|
for(i=0; i<len; i++)
|
|
{
|
|
if(*wbuf != *rbuf)
|
|
{
|
|
fprintf(stderr, "\nERROR, byte %d, written 0x%02x, read 0x%02x\n", i, *wbuf, *rbuf);
|
|
ret++;
|
|
}
|
|
wbuf++;
|
|
rbuf++;
|
|
}
|
|
return(ret);
|
|
}
|
|
|
|
|
|
/* EOF */
|