2002-03-16 12:17:53 +08:00
|
|
|
/*
|
|
|
|
* libpri: An implementation of Primary Rate ISDN
|
|
|
|
*
|
2005-06-22 06:47:39 +08:00
|
|
|
* Written by Mark Spencer <markster@digium.com>
|
2002-03-16 12:17:53 +08:00
|
|
|
*
|
2008-08-06 06:18:12 +08:00
|
|
|
* Copyright (C) 2001-2005, Digium, Inc.
|
2002-03-16 12:17:53 +08:00
|
|
|
* All Rights Reserved.
|
2008-08-06 06:18:12 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
2002-03-16 12:17:53 +08:00
|
|
|
*
|
2008-08-06 06:18:12 +08:00
|
|
|
* 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.
|
2002-03-16 12:17:53 +08:00
|
|
|
*
|
2008-08-06 06:18:12 +08:00
|
|
|
* In addition, when this program is distributed with Asterisk in
|
|
|
|
* any form that would qualify as a 'combined work' or as a
|
|
|
|
* 'derivative work' (but not mere aggregation), you can redistribute
|
|
|
|
* and/or modify the combination under the terms of the license
|
|
|
|
* provided with that copy of Asterisk, instead of the license
|
|
|
|
* terms granted here.
|
2002-03-16 12:17:53 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This program tests libpri call reception using a zaptel interface.
|
|
|
|
* Its state machines are setup for RECEIVING CALLS ONLY, so if you
|
|
|
|
* are trying to both place and receive calls you have to a bit more.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/select.h>
|
2004-05-22 12:25:53 +08:00
|
|
|
#include <sys/types.h>
|
2012-08-11 08:42:04 +08:00
|
|
|
#include <dahdi/user.h>
|
2002-03-16 12:17:53 +08:00
|
|
|
#include "libpri.h"
|
|
|
|
#include "pri_q921.h"
|
|
|
|
#include "pri_q931.h"
|
|
|
|
|
|
|
|
static int pri_open(char *dev)
|
|
|
|
{
|
|
|
|
int dfd;
|
2012-08-11 08:42:04 +08:00
|
|
|
struct dahdi_params p;
|
2002-03-16 12:17:53 +08:00
|
|
|
|
|
|
|
dfd = open(dev, O_RDWR);
|
|
|
|
if (dfd < 0) {
|
|
|
|
fprintf(stderr, "Failed to open dchannel '%s': %s\n", dev, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
2012-08-11 08:42:04 +08:00
|
|
|
if (ioctl(dfd, DAHDI_GET_PARAMS, &p)) {
|
2002-03-16 12:17:53 +08:00
|
|
|
fprintf(stderr, "Unable to get parameters on '%s': %s\n", dev, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
2012-08-11 08:42:04 +08:00
|
|
|
if ((p.sigtype != DAHDI_SIG_HDLCRAW) && (p.sigtype != DAHDI_SIG_HDLCFCS)) {
|
2002-03-16 12:17:53 +08:00
|
|
|
fprintf(stderr, "%s is in %d signalling, not FCS HDLC or RAW HDLC mode\n", dev, p.sigtype);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return dfd;
|
|
|
|
}
|
|
|
|
|
2005-07-27 21:14:05 +08:00
|
|
|
static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
|
2002-03-16 12:17:53 +08:00
|
|
|
{
|
|
|
|
q921_h *h = (q921_h *)buf;
|
2012-02-04 07:12:57 +08:00
|
|
|
q921_dump(pri, h, len, PRI_DEBUG_ALL, txrx);
|
2002-03-16 12:17:53 +08:00
|
|
|
if (!((h->h.data[0] & Q921_FRAMETYPE_MASK) & 0x3)) {
|
2010-04-20 06:40:41 +08:00
|
|
|
q931_dump(pri, h->h.tei, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
|
2002-03-16 12:17:53 +08:00
|
|
|
}
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-09-10 23:52:31 +08:00
|
|
|
static void pri_bridge(int d1, int d2)
|
2002-03-16 12:17:53 +08:00
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
fd_set fds;
|
|
|
|
int max;
|
|
|
|
int e;
|
|
|
|
int res;
|
|
|
|
for(;;) {
|
|
|
|
FD_ZERO(&fds);
|
|
|
|
FD_SET(d1, &fds);
|
|
|
|
FD_SET(d2, &fds);
|
|
|
|
max = d1;
|
|
|
|
if (max < d2)
|
|
|
|
max = d2;
|
2012-08-11 08:42:04 +08:00
|
|
|
ioctl(d1, DAHDI_GETEVENT, &e);
|
|
|
|
ioctl(d2, DAHDI_GETEVENT, &e);
|
2002-03-16 12:17:53 +08:00
|
|
|
res = select(max + 1, &fds, NULL, NULL, NULL);
|
|
|
|
if (res < 0) {
|
|
|
|
fprintf(stderr, "Select returned %d: %s\n", res, strerror(errno));
|
|
|
|
continue;
|
|
|
|
};
|
|
|
|
if (FD_ISSET(d1, &fds)) {
|
|
|
|
/* Copy from d1 to d2 */
|
|
|
|
res = read(d1, buf, sizeof(buf));
|
2005-07-27 21:14:05 +08:00
|
|
|
dump_packet((struct pri *)NULL, buf, res, 1);
|
2002-03-16 12:17:53 +08:00
|
|
|
res = write(d2, buf, res);
|
|
|
|
}
|
|
|
|
if (FD_ISSET(d2, &fds)) {
|
|
|
|
/* Copy from d2 to d1 */
|
|
|
|
res = read(d2, buf, sizeof(buf));
|
2005-07-27 21:14:05 +08:00
|
|
|
dump_packet((struct pri *)NULL, buf, res, 0);
|
2002-03-16 12:17:53 +08:00
|
|
|
res = write(d1, buf, res);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-27 21:14:05 +08:00
|
|
|
static void my_pri_message(struct pri *pri, char *stuff)
|
|
|
|
{
|
|
|
|
fprintf(stdout, "%s", stuff);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void my_pri_error(struct pri *pri, char *stuff)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s", stuff);
|
|
|
|
}
|
|
|
|
|
2002-03-16 12:17:53 +08:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int d1, d2;
|
|
|
|
|
|
|
|
if (argc < 3) {
|
|
|
|
fprintf(stderr, "Usage: pridump <dev1> <dev2>\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2005-07-27 21:14:05 +08:00
|
|
|
pri_set_message(my_pri_message);
|
|
|
|
pri_set_error(my_pri_error);
|
|
|
|
|
2002-03-16 12:17:53 +08:00
|
|
|
d1 = pri_open(argv[1]);
|
|
|
|
if (d1 < 0)
|
|
|
|
exit(1);
|
|
|
|
d2 = pri_open(argv[2]);
|
|
|
|
if (d2 < 0)
|
|
|
|
exit(1);
|
|
|
|
pri_bridge(d1, d2);
|
|
|
|
return 0;
|
|
|
|
}
|