Ignore files generated in the dependency checks.
[libpri-bristuff.git] / testprilib.c
blobc2e89931521d721c9f5075035ca439ce872eafd2
1 /*
2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@digium.com>
6 * Copyright (C) 2001-2005, Digium, Inc.
7 * All Rights Reserved.
8 */
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
27 * terms granted here.
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.
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <sys/ioctl.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <sys/signal.h>
45 #include <sys/select.h>
46 #include <sys/wait.h>
47 #include <sys/resource.h>
48 #include <sys/time.h>
49 #include <netinet/in.h>
50 #include <sys/socket.h>
51 #include <zaptel/zaptel.h>
52 #ifndef SOLARIS
53 #include <zap.h>
54 #endif
55 #include <pthread.h>
56 #include <sys/select.h>
57 #include "libpri.h"
58 #include "pri_q931.h"
60 #ifndef AF_LOCAL
61 #define AF_LOCAL AF_UNIX
62 #endif
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;
73 #define TEST_CALLS 32
75 static void event1(struct pri *pri, pri_event *e)
77 /* Network */
78 int x;
79 static q931_call *calls[TEST_CALLS];
80 char name[256], num[256], dest[256];
81 switch(e->gen.e) {
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");
90 continue;
92 #if 0
94 struct pri_sr *sr;
95 sr = pri_sr_new();
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))
102 perror("pri_setup");
103 pri_sr_free(sr);
105 #else
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)) {
109 perror("pri_call");
111 #endif
113 printf("Setup %d calls!\n", TEST_CALLS);
114 break;
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);
119 break;
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);
123 break;
124 default:
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)
131 /* CPE */
132 switch(e->gen.e) {
133 case PRI_EVENT_RING:
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);
137 break;
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);
141 break;
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);
145 break;
146 case PRI_EVENT_DCHAN_UP:
147 default:
148 printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
152 static void testmsg(struct pri *pri, char *s)
154 char *c;
155 static int keeplast = 0;
156 do {
157 c = strchr(s, '\n');
158 if (c) {
159 *c = '\0';
160 c++;
162 if (keeplast)
163 printf("%s", s);
164 else if (cur == first)
165 printf("-1 %s", s);
166 else
167 printf("-2 %s", s);
168 if (c)
169 printf("\n");
170 s = c;
171 } while(c && *c);
172 if (!c)
173 keeplast = 1;
174 else
175 keeplast = 0;
178 static void testerr(struct pri *pri, char *s)
180 char *c;
181 static int keeplast = 0;
182 do {
183 c = strchr(s, '\n');
184 if (c) {
185 *c = '\0';
186 c++;
188 if (keeplast)
189 printf("%s", s);
190 else if (cur == first)
191 printf("=1 %s", s);
192 else
193 printf("=2 %s", s);
194 if (c)
195 printf("\n");
196 s = c;
197 } while(c && *c);
198 if (!c)
199 keeplast = 1;
200 else
201 keeplast = 0;
205 static void *dchan(void *data)
207 /* Joint D-channel */
208 struct pri *pri = data;
209 struct timeval *next, tv;
210 pri_event *e;
211 fd_set fds;
212 int res;
213 for(;;) {
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;
220 tv.tv_sec -= 1;
222 if (tv.tv_sec < 0) {
223 tv.tv_sec = 0;
224 tv.tv_usec = 0;
227 FD_ZERO(&fds);
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);
231 cur = pri;
232 if (res < 0) {
233 perror("select");
234 } else if (!res) {
235 e = pri_schedule_run(pri);
236 } else {
237 e = pri_check_event(pri);
239 if (e) {
240 if (first == pri) {
241 event1(pri, e);
242 } else {
243 event2(pri, e);
246 pthread_mutex_unlock(&lock);
248 return NULL;
252 int main(int argc, char *argv[])
254 int pair[2];
255 pthread_t tmp;
256 struct pri *pri;
257 pri_set_message(testmsg);
258 pri_set_error(testerr);
259 if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, pair)) {
260 perror("socketpair");
261 exit(1);
263 if (!(pri = pri_new(pair[0], PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
264 perror("pri(0)");
265 exit(1);
267 first = pri;
268 pri_set_debug(pri, DEBUG_LEVEL);
269 pri_facility_enable(pri);
270 if (pthread_create(&tmp, NULL, dchan, pri)) {
271 perror("thread(0)");
272 exit(1);
274 if (!(pri = pri_new(pair[1], PRI_CPE, PRI_DEF_SWITCHTYPE))) {
275 perror("pri(1)");
276 exit(1);
278 pri_set_debug(pri, DEBUG_LEVEL);
279 pri_facility_enable(pri);
280 if (pthread_create(&tmp, NULL, dchan, pri)) {
281 perror("thread(1)");
282 exit(1);
284 /* Wait for things to run */
285 sleep(5);
286 exit(0);