1 /*
2  * libpri: An implementation of Primary Rate ISDN
3  *
4  * Written by Mark Spencer <markster@digium.com>
5  *
6  * Copyright (C) 2001-2005, Digium, Inc.
7  * All Rights Reserved.
8  */
9 
10 /*
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.
16  *
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.
21  *
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.
28  */
29 
30 
31 /*
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.
35  */
36 
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 <pthread.h>
52 #include <sys/select.h>
53 #include "libpri.h"
54 #include "pri_q921.h"
55 #include "pri_q931.h"
56 
57 #ifndef AF_LOCAL
58 #define AF_LOCAL AF_UNIX
59 #endif
60 
61 #define DEBUG_LEVEL	PRI_DEBUG_ALL
62 
63 #define PRI_DEF_NODETYPE	PRI_CPE
64 #define PRI_DEF_SWITCHTYPE	PRI_SWITCH_NI2
65 
66 static struct pri *first;
67 
68 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
69 
70 #define TEST_CALLS 1
71 
event1(struct pri * pri,pri_event * e)72 static void event1(struct pri *pri, pri_event *e)
73 {
74 	/* Network */
75 	int x;
76 	static q931_call *calls[TEST_CALLS];
77 	char name[256], num[256], dest[256];
78 	switch(e->gen.e) {
79 	case PRI_EVENT_DCHAN_UP:
80 		printf("Network is up.  Sending blast of calls!\n");
81 		for (x=0;x<TEST_CALLS;x++) {
82 			sprintf(name, "Caller %d", x + 1);
83 			sprintf(num, "25642860%02d", x+1);
84 			sprintf(dest, "60%02d", x + 1);
85 			if (!(calls[x] = pri_new_call(pri))) {
86 				perror("pri_new_call");
87 				continue;
88 			}
89 #if 0
90 			{
91 				struct pri_sr *sr;
92 				sr = pri_sr_new();
93 				pri_sr_set_channel(sr, x+1, 0, 0);
94 				pri_sr_set_bearer(sr, 0, PRI_LAYER_1_ULAW);
95 				pri_sr_set_called(sr, dest, PRI_NATIONAL_ISDN, 1);
96 				pri_sr_set_caller(sr, num, name, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
97 				pri_sr_set_redirecting(sr, num, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
98 				if (pri_setup(pri, calls[x], sr))
99 					perror("pri_setup");
100 				pri_sr_free(sr);
101 			}
102 #else
103 			if (pri_call(pri, calls[x], PRI_TRANS_CAP_DIGITAL, x + 1, 1, 1, num,
104 				PRI_NATIONAL_ISDN, name, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
105 				dest, PRI_NATIONAL_ISDN, PRI_LAYER_1_ULAW)) {
106 					perror("pri_call");
107 			}
108 #endif
109 		}
110 		printf("Setup %d calls!\n", TEST_CALLS);
111 		break;
112 	case PRI_EVENT_RINGING:
113 		printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
114 		q931_facility(pri, e->ringing.call);
115 		pri_answer(pri, e->ringing.call, e->ringing.channel, 0);
116 		break;
117 	case PRI_EVENT_HANGUP_REQ:
118 		printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
119 		pri_hangup(pri, e->hangup.call, e->hangup.cause);
120 		break;
121 	default:
122 		printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
123 	}
124 }
125 
event2(struct pri * pri,pri_event * e)126 static void event2(struct pri *pri, pri_event *e)
127 {
128 	/* CPE */
129 	switch(e->gen.e) {
130 	case PRI_EVENT_RING:
131 		printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
132 		pri_proceeding(pri, e->ring.call, e->ring.channel, 0);
133 		pri_acknowledge(pri, e->ring.call, e->ring.channel, 0);
134 		break;
135 	case PRI_EVENT_ANSWER:
136 		printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
137 		pri_hangup(pri, e->answer.call, PRI_CAUSE_NORMAL_UNSPECIFIED);
138 		break;
139 	case PRI_EVENT_HANGUP:
140 		printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
141 		pri_hangup(pri, e->hangup.call, e->hangup.cause);
142 		break;
143 	case PRI_EVENT_DCHAN_UP:
144 	default:
145 		printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
146 	}
147 }
148 
testmsg(struct pri * pri,char * s)149 static void testmsg(struct pri *pri, char *s)
150 {
151 	char *c;
152 	static int keeplast = 0;
153 	do {
154 		c = strchr(s, '\n');
155 		if (c) {
156 			*c = '\0';
157 			c++;
158 		}
159 		if (keeplast || !pri)
160 			printf("%s", s);
161 		else if (pri == first)
162 			printf("-1 %s", s);
163 		else
164 			printf("-2 %s", s);
165 		if (c)
166 			printf("\n");
167 		s = c;
168 	} while(c && *c);
169 	if (!c)
170 		keeplast = 1;
171 	else
172 		keeplast = 0;
173 }
174 
testerr(struct pri * pri,char * s)175 static void testerr(struct pri *pri, char *s)
176 {
177 	char *c;
178 	static int keeplast = 0;
179 	do {
180 		c = strchr(s, '\n');
181 		if (c) {
182 			*c = '\0';
183 			c++;
184 		}
185 		if (keeplast || !pri)
186 			printf("%s", s);
187 		else if (pri == first)
188 			printf("=1 %s", s);
189 		else
190 			printf("=2 %s", s);
191 		if (c)
192 			printf("\n");
193 		s = c;
194 	} while(c && *c);
195 	if (!c)
196 		keeplast = 1;
197 	else
198 		keeplast = 0;
199 }
200 
201 
dchan(void * data)202 static void *dchan(void *data)
203 {
204 	/* Joint D-channel */
205 	struct pri *pri = data;
206 	struct timeval *next, tv;
207 	pri_event *e = NULL;
208 	fd_set fds;
209 	int res;
210 	for(;;) {
211 		if ((next = pri_schedule_next(pri))) {
212 			gettimeofday(&tv, NULL);
213 			tv.tv_sec = next->tv_sec - tv.tv_sec;
214 			tv.tv_usec = next->tv_usec - tv.tv_usec;
215 			if (tv.tv_usec < 0) {
216 				tv.tv_usec += 1000000;
217 				tv.tv_sec -= 1;
218 			}
219 			if (tv.tv_sec < 0) {
220 				tv.tv_sec = 0;
221 				tv.tv_usec = 0;
222 			}
223 		}
224 		FD_ZERO(&fds);
225 		FD_SET(pri_fd(pri), &fds);
226 		res = select(pri_fd(pri) + 1, &fds, NULL, NULL, next ? &tv : NULL);
227 		pthread_mutex_lock(&lock);
228 		if (res < 0) {
229 			perror("select");
230 		} else if (!res) {
231 			e = pri_schedule_run(pri);
232 		} else {
233 			e = pri_check_event(pri);
234 		}
235 		if (e) {
236 			if (first == pri) {
237 				event1(pri, e);
238 			} else {
239 				event2(pri, e);
240 			}
241 		}
242 		pthread_mutex_unlock(&lock);
243 	}
244 	return NULL;
245 }
246 
247 
main(int argc,char * argv[])248 int main(int argc, char *argv[])
249 {
250 	int pair[2];
251 	pthread_t tmp;
252 	struct pri *pri;
253 	pri_set_message(testmsg);
254 	pri_set_error(testerr);
255 	if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, pair)) {
256 		perror("socketpair");
257 		exit(1);
258 	}
259 	if (!(pri = pri_new_bri(pair[0], 0, PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
260 		perror("pri(0)");
261 		exit(1);
262 	}
263 	first = pri;
264 	pri_set_debug(pri, DEBUG_LEVEL);
265 	pri_facility_enable(pri);
266 	if (pthread_create(&tmp, NULL, dchan, pri)) {
267 		perror("thread(0)");
268 		exit(1);
269 	}
270 	if (!(pri = pri_new_bri(pair[1], 0, PRI_CPE, PRI_DEF_SWITCHTYPE))) {
271 		perror("pri(1)");
272 		exit(1);
273 	}
274 	pri_set_debug(pri, DEBUG_LEVEL);
275 	pri_facility_enable(pri);
276 	if (pthread_create(&tmp, NULL, dchan, pri)) {
277 		perror("thread(1)");
278 		exit(1);
279 	}
280 	/* Wait for things to run */
281 	sleep(5);
282 	exit(0);
283 }
284 
285