2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@digium.com>
6 * Copyright (C) 2001-2005, Digium, Inc.
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2 as published by the
19 * Free Software Foundation. See the LICENSE file included with
20 * this program for more details.
22 * In addition, when this program is distributed with Asterisk in
23 * any form that would qualify as a 'combined work' or as a
24 * 'derivative work' (but not mere aggregation), you can redistribute
25 * and/or modify the combination under the terms of the license
26 * provided with that copy of Asterisk, instead of the license
32 * This program tests libpri call reception using a zaptel interface.
33 * Its state machines are setup for RECEIVING CALLS ONLY, so if you
34 * are trying to both place and receive calls you have to a bit more.
41 #include <sys/ioctl.h>
44 #include <sys/signal.h>
45 #include <sys/select.h>
47 #include <sys/resource.h>
49 #include <netinet/in.h>
50 #include <sys/socket.h>
51 #include <zaptel/zaptel.h>
56 #include <sys/select.h>
61 #define AF_LOCAL AF_UNIX
64 #define DEBUG_LEVEL PRI_DEBUG_ALL
66 #define PRI_DEF_NODETYPE PRI_CPE
67 #define PRI_DEF_SWITCHTYPE PRI_SWITCH_NI2
69 static struct pri
*first
, *cur
;
71 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
75 static void event1(struct pri
*pri
, pri_event
*e
)
79 static q931_call
*calls
[TEST_CALLS
];
80 char name
[256], num
[256], dest
[256];
82 case PRI_EVENT_DCHAN_UP
:
83 printf("Network is up. Sending blast of calls!\n");
84 for (x
=0;x
<TEST_CALLS
;x
++) {
85 sprintf(name
, "Caller %d", x
+ 1);
86 sprintf(num
, "25642860%02d", x
+1);
87 sprintf(dest
, "60%02d", x
+ 1);
88 if (!(calls
[x
] = pri_new_call(pri
))) {
89 perror("pri_new_call");
96 pri_sr_set_channel(sr
, x
+1, 0, 0);
97 pri_sr_set_bearer(sr
, 0, PRI_LAYER_1_ULAW
);
98 pri_sr_set_called(sr
, dest
, PRI_NATIONAL_ISDN
, 1);
99 pri_sr_set_caller(sr
, num
, name
, PRI_NATIONAL_ISDN
, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
);
100 pri_sr_set_redirecting(sr
, num
, PRI_NATIONAL_ISDN
, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
, PRI_REDIR_UNCONDITIONAL
);
101 if (pri_setup(pri
, calls
[x
], sr
))
106 if (pri_call(pri
, calls
[x
], PRI_TRANS_CAP_DIGITAL
, x
+ 1, 1, 1, num
,
107 PRI_NATIONAL_ISDN
, name
, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
,
108 dest
, PRI_NATIONAL_ISDN
, PRI_LAYER_1_ULAW
)) {
113 printf("Setup %d calls!\n", TEST_CALLS
);
115 case PRI_EVENT_RINGING
:
116 printf("PRI 1: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
117 q931_facility(pri
, e
->ringing
.call
);
118 pri_answer(pri
, e
->ringing
.call
, e
->ringing
.channel
, 0);
120 case PRI_EVENT_HANGUP_REQ
:
121 printf("PRI 1: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
122 pri_hangup(pri
, e
->hangup
.call
, e
->hangup
.cause
);
125 printf("PRI 1: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
129 static void event2(struct pri
*pri
, pri_event
*e
)
134 printf("PRI 2: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
135 pri_proceeding(pri
, e
->ring
.call
, e
->ring
.channel
, 0);
136 pri_acknowledge(pri
, e
->ring
.call
, e
->ring
.channel
, 0);
138 case PRI_EVENT_ANSWER
:
139 printf("PRI 2: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
140 pri_hangup(pri
, e
->answer
.call
, PRI_CAUSE_NORMAL_UNSPECIFIED
);
142 case PRI_EVENT_HANGUP
:
143 printf("PRI 2: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
144 pri_hangup(pri
, e
->hangup
.call
, e
->hangup
.cause
);
146 case PRI_EVENT_DCHAN_UP
:
148 printf("PRI 2: %s (%d)\n", pri_event2str(e
->gen
.e
), e
->gen
.e
);
152 static void testmsg(struct pri
*pri
, char *s
)
155 static int keeplast
= 0;
164 else if (cur
== first
)
178 static void testerr(struct pri
*pri
, char *s
)
181 static int keeplast
= 0;
190 else if (cur
== first
)
205 static void *dchan(void *data
)
207 /* Joint D-channel */
208 struct pri
*pri
= data
;
209 struct timeval
*next
, tv
;
214 if ((next
= pri_schedule_next(pri
))) {
215 gettimeofday(&tv
, NULL
);
216 tv
.tv_sec
= next
->tv_sec
- tv
.tv_sec
;
217 tv
.tv_usec
= next
->tv_usec
- tv
.tv_usec
;
218 if (tv
.tv_usec
< 0) {
219 tv
.tv_usec
+= 1000000;
228 FD_SET(pri_fd(pri
), &fds
);
229 res
= select(pri_fd(pri
) + 1, &fds
, NULL
, NULL
, next
? &tv
: NULL
);
230 pthread_mutex_lock(&lock
);
235 e
= pri_schedule_run(pri
);
237 e
= pri_check_event(pri
);
246 pthread_mutex_unlock(&lock
);
252 int main(int argc
, char *argv
[])
257 pri_set_message(testmsg
);
258 pri_set_error(testerr
);
259 if (socketpair(AF_LOCAL
, SOCK_DGRAM
, 0, pair
)) {
260 perror("socketpair");
263 if (!(pri
= pri_new(pair
[0], PRI_NETWORK
, PRI_DEF_SWITCHTYPE
))) {
268 pri_set_debug(pri
, DEBUG_LEVEL
);
269 pri_facility_enable(pri
);
270 if (pthread_create(&tmp
, NULL
, dchan
, pri
)) {
274 if (!(pri
= pri_new(pair
[1], PRI_CPE
, PRI_DEF_SWITCHTYPE
))) {
278 pri_set_debug(pri
, DEBUG_LEVEL
);
279 pri_facility_enable(pri
);
280 if (pthread_create(&tmp
, NULL
, dchan
, pri
)) {
284 /* Wait for things to run */