1998-12-27 21:47:14 +00:00
|
|
|
/*
|
1999-03-07 16:12:47 +00:00
|
|
|
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
|
1998-12-27 21:47:14 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* -----------------------------
|
|
|
|
*
|
2000-10-09 14:22:51 +00:00
|
|
|
* $Id: main.c,v 1.16 2000/03/13 16:18:38 hm Exp $
|
1998-12-27 21:47:14 +00:00
|
|
|
*
|
1999-12-14 21:14:28 +00:00
|
|
|
* $FreeBSD$
|
|
|
|
*
|
2000-10-09 14:22:51 +00:00
|
|
|
* last edit-date: [Mon Mar 13 17:19:26 2000]
|
1998-12-27 21:47:14 +00:00
|
|
|
*
|
|
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
1999-12-14 21:14:28 +00:00
|
|
|
/*---------------------------------------------------------------------------*
|
|
|
|
* usage display and exit
|
|
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
static void
|
|
|
|
usage(void)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "isdntest - i4b selftest, version %d.%d.%d, compiled %s %s\n",VERSION, REL, STEP, __DATE__, __TIME__);
|
|
|
|
fprintf(stderr, "usage: isdntest [-c ctrl] [-d level] [-h] [-i telno] [-o telno] [-t num] [-w]\n");
|
|
|
|
fprintf(stderr, " -c <ctrl> specify controller to use\n");
|
|
|
|
fprintf(stderr, " -d <level> set debug level\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, " -t <num> send test pattern num times\n");
|
|
|
|
fprintf(stderr, " -w wait for keyboard entry to disconnect\n");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
1998-12-27 21:47:14 +00:00
|
|
|
/*---------------------------------------------------------------------------*
|
|
|
|
* 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';
|
|
|
|
|
1999-06-24 06:43:21 +00:00
|
|
|
while ((c = getopt(argc, argv, "c:d:hi:o:t:w")) != -1)
|
1998-12-27 21:47:14 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
|
|
* 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();
|
2000-10-09 14:22:51 +00:00
|
|
|
exit(0);
|
1998-12-27 21:47:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
|
|
* 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))
|
|
|
|
{
|
2000-10-09 14:22:51 +00:00
|
|
|
if(debug_level)
|
|
|
|
fprintf(stderr, "isdntest: cleanup, out_cdid %d, in_cdid %d\n", out_cdid, in_cdid);
|
1998-12-27 21:47:14 +00:00
|
|
|
|
|
|
|
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:
|
2000-10-09 14:22:51 +00:00
|
|
|
if(debug_level)
|
|
|
|
fprintf(stderr, "isdntest: unknown message 0x%x = %c\n", buf[0], buf[0]);
|
1998-12-27 21:47:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf(stderr, "isdntest: read error, errno = %d, length = %d", errno, len);
|
|
|
|
}
|
|
|
|
}
|
2000-10-09 14:22:51 +00:00
|
|
|
if(debug_level)
|
|
|
|
fprintf(stderr, "isdntest: exit cleanup, out_cdid %d, in_cdid %d\n", out_cdid, in_cdid);
|
1998-12-27 21:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
|
|
* 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 */
|