Ignore files generated in the dependency checks.
[libpri-bristuff.git] / pri.c
blob3c8898b4c71b7cb7984a2d910ca5054dcfdf999d
1 /*
2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@linux-suppot.net>
6 * Copyright (C) 2001-2005, Digium, Inc.
7 * All Rights Reserved.
8 * Copyright (C) 2003-2006 Junghanns.NET GmbH
9 * Klaus-Peter Junghanns <kpj@junghanns.net>
13 * See http://www.asterisk.org for more information about
14 * the Asterisk project. Please do not directly contact
15 * any of the maintainers of this project for assistance;
16 * the project provides a web site, mailing lists and IRC
17 * channels for your use.
19 * This program is free software, distributed under the terms of
20 * the GNU General Public License Version 2 as published by the
21 * Free Software Foundation. See the LICENSE file included with
22 * this program for more details.
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <sys/select.h>
33 #include <stdarg.h>
34 #include "compat.h"
35 #include "libpri.h"
36 #include "pri_internal.h"
37 #include "pri_facility.h"
38 #include "pri_q921.h"
39 #include "pri_q931.h"
40 #include "pri_timers.h"
42 char *pri_node2str(int node)
44 switch(node) {
45 case PRI_UNKNOWN:
46 return "Unknown node type";
47 case PRI_NETWORK:
48 return "Network";
49 case PRI_CPE:
50 return "CPE";
51 case BRI_NETWORK:
52 return "Network";
53 case BRI_CPE:
54 return "CPE";
55 case BRI_NETWORK_PTMP:
56 return "Network (PtMP)";
57 case BRI_CPE_PTMP:
58 return "CPE (PtMP)";
59 default:
60 return "Invalid value";
64 char *pri_switch2str(int sw)
66 switch(sw) {
67 case PRI_SWITCH_NI2:
68 return "National ISDN";
69 case PRI_SWITCH_DMS100:
70 return "Nortel DMS100";
71 case PRI_SWITCH_LUCENT5E:
72 return "Lucent 5E";
73 case PRI_SWITCH_ATT4ESS:
74 return "AT&T 4ESS";
75 case PRI_SWITCH_NI1:
76 return "National ISDN 1";
77 case PRI_SWITCH_EUROISDN_E1:
78 return "EuroISDN";
79 case PRI_SWITCH_GR303_EOC:
80 return "GR303 EOC";
81 case PRI_SWITCH_GR303_TMC:
82 return "GR303 TMC";
83 case PRI_SWITCH_QSIG:
84 return "Q.SIG switch";
85 default:
86 return "Unknown switchtype";
90 static void pri_default_timers(struct pri *pri, int switchtype)
92 int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
93 int x;
95 for (x = 0; x<PRI_MAX_TIMERS; x++) {
96 pri->timers[x] = defaulttimers[switchtype][x];
100 int pri_set_timer(struct pri *pri, int timer, int value)
102 if (timer < 0 || timer > PRI_MAX_TIMERS || value < 0)
103 return -1;
105 pri->timers[timer] = value;
106 return 0;
109 int pri_get_timer(struct pri *pri, int timer)
111 if (timer < 0 || timer > PRI_MAX_TIMERS)
112 return -1;
113 return pri->timers[timer];
116 int pri_timer2idx(char *timer)
118 if (!strcasecmp(timer, "N200"))
119 return PRI_TIMER_N200;
120 else if (!strcasecmp(timer, "N201"))
121 return PRI_TIMER_N201;
122 else if (!strcasecmp(timer, "N202"))
123 return PRI_TIMER_N202;
124 else if (!strcasecmp(timer, "K"))
125 return PRI_TIMER_K;
126 else if (!strcasecmp(timer, "T200"))
127 return PRI_TIMER_T200;
128 else if (!strcasecmp(timer, "T202"))
129 return PRI_TIMER_T202;
130 else if (!strcasecmp(timer, "T203"))
131 return PRI_TIMER_T203;
132 else if (!strcasecmp(timer, "T300"))
133 return PRI_TIMER_T300;
134 else if (!strcasecmp(timer, "T301"))
135 return PRI_TIMER_T301;
136 else if (!strcasecmp(timer, "T302"))
137 return PRI_TIMER_T302;
138 else if (!strcasecmp(timer, "T303"))
139 return PRI_TIMER_T303;
140 else if (!strcasecmp(timer, "T304"))
141 return PRI_TIMER_T304;
142 else if (!strcasecmp(timer, "T305"))
143 return PRI_TIMER_T305;
144 else if (!strcasecmp(timer, "T306"))
145 return PRI_TIMER_T306;
146 else if (!strcasecmp(timer, "T307"))
147 return PRI_TIMER_T307;
148 else if (!strcasecmp(timer, "T308"))
149 return PRI_TIMER_T308;
150 else if (!strcasecmp(timer, "T309"))
151 return PRI_TIMER_T309;
152 else if (!strcasecmp(timer, "T310"))
153 return PRI_TIMER_T310;
154 else if (!strcasecmp(timer, "T313"))
155 return PRI_TIMER_T313;
156 else if (!strcasecmp(timer, "T314"))
157 return PRI_TIMER_T314;
158 else if (!strcasecmp(timer, "T316"))
159 return PRI_TIMER_T316;
160 else if (!strcasecmp(timer, "T317"))
161 return PRI_TIMER_T317;
162 else if (!strcasecmp(timer, "T318"))
163 return PRI_TIMER_T318;
164 else if (!strcasecmp(timer, "T319"))
165 return PRI_TIMER_T319;
166 else if (!strcasecmp(timer, "T320"))
167 return PRI_TIMER_T320;
168 else if (!strcasecmp(timer, "T321"))
169 return PRI_TIMER_T321;
170 else if (!strcasecmp(timer, "T322"))
171 return PRI_TIMER_T322;
172 else
173 return -1;
176 static int __pri_read(struct pri *pri, void *buf, int buflen)
178 int res = read(pri->fd, buf, buflen);
179 if (res < 0) {
180 if (errno != EAGAIN)
181 pri_error(pri, "Read on %d failed: %s\n", pri->fd, strerror(errno));
182 return 0;
184 return res;
187 static int __pri_write(struct pri *pri, void *buf, int buflen)
189 int res = write(pri->fd, buf, buflen);
190 if (res < 0) {
191 if (errno != EAGAIN)
192 pri_error(pri, "Write to %d failed: %s\n", pri->fd, strerror(errno));
193 return 0;
195 return res;
198 static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int span)
200 struct pri *p;
201 p = malloc(sizeof(struct pri));
202 if (p) {
203 memset(p, 0, sizeof(struct pri));
204 p->fd = fd;
205 p->read_func = rd;
206 p->write_func = wr;
207 p->userdata = userdata;
208 p->localtype = node;
209 p->switchtype = switchtype;
210 p->cref = 1;
211 p->sapi = Q921_SAPI_CALL_CTRL;
212 p->tei = 0;
213 p->nsf = PRI_NSF_NONE;
214 p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
215 p->master = master;
216 p->callpool = &p->localpool;
217 pri_default_timers(p, switchtype);
218 p->debugfd = -1;
219 p->span = span;
220 #ifdef LIBPRI_COUNTERS
221 p->q921_rxcount = 0;
222 p->q921_txcount = 0;
223 p->q931_rxcount = 0;
224 p->q931_txcount = 0;
225 #endif
226 if (switchtype == PRI_SWITCH_GR303_EOC) {
227 p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
228 p->sapi = Q921_SAPI_GR303_EOC;
229 p->tei = Q921_TEI_GR303_EOC_OPS;
230 p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, span);
231 if (!p->subchannel) {
232 free(p);
233 p = NULL;
235 } else if (switchtype == PRI_SWITCH_GR303_TMC) {
236 p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
237 p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
238 p->tei = Q921_TEI_GR303_TMC_CALLPROC;
239 p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, span);
240 if (!p->subchannel) {
241 free(p);
242 p = NULL;
244 } else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
245 p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
246 p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
247 p->tei = Q921_TEI_GR303_TMC_SWITCHING;
248 } else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
249 p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
250 p->sapi = Q921_SAPI_GR303_EOC;
251 p->tei = Q921_TEI_GR303_EOC_PATH;
253 /* Start Q.921 layer, Wait if we're the network */
254 if (p)
255 q921_start(p, p->localtype == PRI_CPE, 0);
257 return p;
260 void pri_call_set_useruser(q931_call *c, const char *userchars)
262 if (userchars)
263 libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
266 void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars)
268 sr->useruserinfo = userchars;
271 int pri_restart(struct pri *pri)
273 /* Restart Q.921 layer */
274 if (pri) {
275 // XXX q921_reset(pri);
276 // q921_start(pri, pri->localtype == PRI_CPE);
278 return 0;
282 struct pri *pri_new(int fd, int nodetype, int switchtype, int span)
284 return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, span);
287 struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
289 if (!io_read)
290 io_read = __pri_read;
291 if (!io_write)
292 io_write = __pri_write;
293 return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, -1);
296 void *pri_get_userdata(struct pri *pri)
298 return pri ? pri->userdata : NULL;
301 void pri_set_userdata(struct pri *pri, void *userdata)
303 if (pri)
304 pri->userdata = userdata;
307 void pri_set_nsf(struct pri *pri, int nsf)
309 if (pri)
310 pri->nsf = nsf;
313 char *pri_event2str(int id)
315 switch(id) {
316 case PRI_EVENT_DCHAN_UP:
317 return "D-Channel Up";
318 case PRI_EVENT_DCHAN_DOWN:
319 return "D-channel Down";
320 case PRI_EVENT_RESTART:
321 return "Restart channel";
322 case PRI_EVENT_RING:
323 return "Ring";
324 case PRI_EVENT_HANGUP:
325 return "Hangup";
326 case PRI_EVENT_RINGING:
327 return "Ringing";
328 case PRI_EVENT_ANSWER:
329 return "Answer";
330 case PRI_EVENT_HANGUP_ACK:
331 return "Hangup ACK";
332 case PRI_EVENT_RESTART_ACK:
333 return "Restart ACK";
334 case PRI_EVENT_FACNAME:
335 return "FacName";
336 case PRI_EVENT_INFO_RECEIVED:
337 return "Info Received";
338 case PRI_EVENT_PROCEEDING:
339 return "Proceeding";
340 case PRI_EVENT_SETUP_ACK:
341 return "Setup ACK";
342 case PRI_EVENT_HANGUP_REQ:
343 return "Hangup Req";
344 case PRI_EVENT_NOTIFY:
345 return "Notify";
346 case PRI_EVENT_PROGRESS:
347 return "Progress";
348 case PRI_EVENT_CONFIG_ERR:
349 return "Configuration Error";
350 default:
351 return "Unknown Event";
355 pri_event *pri_check_event(struct pri *pri)
357 char buf[1024];
358 int res;
359 pri_event *e;
360 res = pri->read_func ? pri->read_func(pri, buf, sizeof(buf)) : 0;
361 if (!res)
362 return NULL;
363 /* Receive the q921 packet */
364 e = q921_receive(pri, (q921_h *)buf, res);
365 return e;
368 static int wait_pri(struct pri *pri)
370 struct timeval *tv, real;
371 fd_set fds;
372 int res;
373 FD_ZERO(&fds);
374 FD_SET(pri->fd, &fds);
375 tv = pri_schedule_next(pri);
376 if (tv) {
377 gettimeofday(&real, NULL);
378 real.tv_sec = tv->tv_sec - real.tv_sec;
379 real.tv_usec = tv->tv_usec - real.tv_usec;
380 if (real.tv_usec < 0) {
381 real.tv_usec += 1000000;
382 real.tv_sec -= 1;
384 if (real.tv_sec < 0) {
385 real.tv_sec = 0;
386 real.tv_usec = 0;
389 res = select(pri->fd + 1, &fds, NULL, NULL, tv ? &real : tv);
390 if (res < 0)
391 return -1;
392 return res;
395 pri_event *pri_mkerror(struct pri *pri, char *errstr)
397 /* Return a configuration error */
398 pri->ev.err.e = PRI_EVENT_CONFIG_ERR;
399 libpri_copy_string(pri->ev.err.err, errstr, sizeof(pri->ev.err.err));
400 return &pri->ev;
404 pri_event *pri_dchannel_run(struct pri *pri, int block)
406 pri_event *e;
407 int res;
408 if (!pri)
409 return NULL;
410 if (block) {
411 do {
412 e = NULL;
413 res = wait_pri(pri);
414 /* Check for error / interruption */
415 if (res < 0)
416 return NULL;
417 if (!res)
418 e = pri_schedule_run(pri);
419 else
420 e = pri_check_event(pri);
421 } while(!e);
422 } else {
423 e = pri_check_event(pri);
424 return e;
426 return e;
429 void pri_set_debug(struct pri *pri, int debug)
431 if (!pri)
432 return;
433 pri->debug = debug;
434 if (pri->subchannel)
435 pri_set_debug(pri->subchannel, debug);
438 int pri_get_debug(struct pri *pri)
440 if (!pri)
441 return -1;
442 if (pri->subchannel)
443 return pri_get_debug(pri->subchannel);
444 return pri->debug;
447 void pri_facility_enable(struct pri *pri)
449 if (!pri)
450 return;
451 pri->sendfacility = 1;
452 if (pri->subchannel)
453 pri_facility_enable(pri->subchannel);
454 return;
457 void pri_set_debug_fd(struct pri *pri, int fd)
459 if (!pri)
460 return;
461 pri->debugfd = fd;
462 if (pri->subchannel)
463 pri_set_debug_fd(pri->subchannel, fd);
466 int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
468 if (!pri || !call)
469 return -1;
470 return q931_alerting(pri, call, channel, info);
473 int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
475 if (!pri || !call)
476 return -1;
477 return q931_call_proceeding(pri, call, channel, info);
480 int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
482 if (!pri || !call)
483 return -1;
484 return q931_call_progress(pri, call, channel, info);
487 int pri_information(struct pri *pri, q931_call *call, char digit)
489 if (!pri || !call)
490 return -1;
491 return q931_information(pri, call, digit);
494 int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits)
496 if (!pri || !call || !digits || !digits[0])
497 return -1;
499 return q931_keypad_facility(pri, call, digits);
502 int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
504 if (!pri || !call)
505 return -1;
506 return q931_notify(pri, call, channel, info);
509 int pri_information_display(struct pri *pri, q931_call *call, char *display)
511 if (!pri || !call)
512 return -1;
513 return q931_information_display(pri, call, display);
516 int pri_add_display(struct pri *pri, q931_call *call, char *display)
518 if (!pri || !call)
519 return -1;
520 return q931_add_display(pri, call, display);
524 void pri_destroycall(struct pri *pri, q931_call *call)
526 if (pri && call)
527 __q931_destroycall(pri, call);
528 return;
531 int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn)
533 if (!pri || !call)
534 return -1;
535 return q931_setup_ack(pri, call, channel, nonisdn);
538 int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
540 if (!pri || !call)
541 return -1;
542 return q931_connect(pri, call, channel, nonisdn);
545 int pri_hold_acknowledge(struct pri *pri, q931_call *call)
547 if (!pri || !call)
548 return -1;
549 return q931_hold_acknowledge(pri, call);
552 int pri_hold_reject(struct pri *pri, q931_call *call)
554 if (!pri || !call)
555 return -1;
556 return q931_hold_reject(pri, call);
559 int pri_retrieve_acknowledge(struct pri *pri, q931_call *call, int channel)
561 if (!pri || !call)
562 return -1;
563 return q931_retrieve_acknowledge(pri, call, channel);
566 int pri_retrieve_reject(struct pri *pri, q931_call *call)
568 if (!pri || !call)
569 return -1;
570 return q931_retrieve_reject(pri, call);
573 int pri_suspend_acknowledge(struct pri *pri, q931_call *call, char *display)
575 if (!pri || !call)
576 return -1;
577 return q931_suspend_acknowledge(pri, call, display);
580 int pri_suspend_reject(struct pri *pri, q931_call *call, char *display)
582 if (!pri || !call)
583 return -1;
584 return q931_suspend_reject(pri, call, display);
587 int pri_resume_reject(struct pri *pri, q931_call *call, char *display)
589 if (!pri || !call)
590 return -1;
591 return q931_resume_reject(pri, call, display);
594 int pri_resume_acknowledge(struct pri *pri, q931_call *call, int channel, char *display)
596 if (!pri || !call)
597 return -1;
598 return q931_resume_acknowledge(pri, call, channel, display);
601 int pri_facility(struct pri *pri, q931_call *call, int operation, char *arguments)
603 if (!pri || !call)
604 return -1;
605 // return q931_facility(pri, call, operation, arguments);
606 return q931_facility(pri, call);
609 int pri_deflect(struct pri *pri, q931_call *call, char *destination)
611 if ((pri->localtype == PRI_CPE) || (pri->localtype == BRI_CPE)) {
612 add_call_rerouting_facility_ie(pri, call, destination);
613 return q931_facility(pri, call);
614 } else if (pri->localtype == BRI_CPE_PTMP) {
615 add_call_deflection_facility_ie(pri, call, destination);
616 return q931_facility(pri, call);
617 } else {
618 return -1;
622 #if 0
623 /* deprecated routines, use pri_hangup */
624 int pri_release(struct pri *pri, q931_call *call, int cause)
626 if (!pri || !call)
627 return -1;
628 return q931_release(pri, call, cause);
631 int pri_disconnect(struct pri *pri, q931_call *call, int cause)
633 if (!pri || !call)
634 return -1;
635 return q931_disconnect(pri, call, cause);
637 #endif
639 int pri_channel_bridge(q931_call *call1, q931_call *call2)
641 if (!call1 || !call2)
642 return -1;
644 /* Make sure we have compatible switchtypes */
645 if (call1->pri->switchtype != call2->pri->switchtype)
646 return -1;
648 /* Check for bearer capability */
649 if (call1->transcapability != call2->transcapability)
650 return -1;
652 /* Check to see if we're on the same PRI */
653 if (call1->pri != call2->pri)
654 return -1;
656 switch (call1->pri->switchtype) {
657 case PRI_SWITCH_NI2:
658 case PRI_SWITCH_LUCENT5E:
659 case PRI_SWITCH_ATT4ESS:
660 if (eect_initiate_transfer(call1->pri, call1, call2))
661 return -1;
662 else
663 return 0;
664 break;
665 case PRI_SWITCH_DMS100:
666 if (rlt_initiate_transfer(call1->pri, call1, call2))
667 return -1;
668 else
669 return 0;
670 break;
671 default:
672 return -1;
676 int pri_hangup(struct pri *pri, q931_call *call, int cause, int aocunits)
678 int res=0;
679 if (!pri || !call)
680 return -1;
681 if (cause == -1)
682 /* normal clear cause */
683 cause = 16;
684 if ((cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81 || cause == 17) && (call->ourcallstate == Q931_CALL_STATE_ACTIVE)) {
685 pri_error(pri, "Cause code %d not allowed when disconnecting an active call. Changing to cause 16.\n", cause);
686 cause = 16;
689 if (aocunits > -1) {
690 call->aoc_units = aocunits;
693 if (pri->localtype == BRI_NETWORK_PTMP) {
694 res = q921_hangup(pri, call, 127);
695 if (res) {
696 // q921_setup might give a HANGUP_ACK, if nobody got the call
697 q931_hangup(pri, call, cause);
698 return res;
699 } else {
700 return q931_hangup(pri, call, cause);
702 } else {
703 return q931_hangup(pri, call, cause);
707 int pri_reset(struct pri *pri, int channel)
709 if (!pri)
710 return -1;
711 return q931_restart(pri, channel);
714 q931_call *pri_new_call(struct pri *pri)
716 if (!pri)
717 return NULL;
718 return q931_new_call(pri);
721 void pri_dump_event(struct pri *pri, pri_event *e)
723 if (!pri || !e)
724 return;
725 pri_message(pri, "Event type: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
726 switch(e->gen.e) {
727 case PRI_EVENT_DCHAN_UP:
728 case PRI_EVENT_DCHAN_DOWN:
729 break;
730 case PRI_EVENT_CONFIG_ERR:
731 pri_message(pri, "Error: %s", e->err.err);
732 break;
733 case PRI_EVENT_RESTART:
734 pri_message(pri, "Restart on channel %d\n", e->restart.channel);
735 case PRI_EVENT_RING:
736 pri_message(pri, "Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
737 pri_message(pri, "Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
738 pri_message(pri, "Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
739 break;
740 case PRI_EVENT_HANGUP:
741 pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
742 break;
743 default:
744 pri_message(pri, "Don't know how to dump events of type %d\n", e->gen.e);
748 static void pri_sr_init(struct pri_sr *req)
750 memset(req, 0, sizeof(struct pri_sr));
754 int pri_sr_set_connection_call_independent(struct pri_sr *req)
756 if (!req)
757 return -1;
759 req->justsignalling = 1; /* have to set justsignalling for all those pesky IEs we need to setup */
760 return 0;
763 /* Don't call any other pri functions on this */
764 int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called,
765 int calledplan)
767 struct pri_sr req;
768 if (!pri || !c)
769 return -1;
771 pri_sr_init(&req);
772 pri_sr_set_connection_call_independent(&req);
774 req.caller = caller;
775 req.callerplan = callerplan;
776 req.callername = callername;
777 req.callerpres = callerpres;
778 req.called = called;
779 req.calledplan = calledplan;
781 if (mwi_message_send(pri, c, &req, 1) < 0) {
782 pri_message(pri, "Unable to send MWI activate message\n");
783 return -1;
785 /* Do more stuff when we figure out that the CISC stuff works */
786 return q931_setup(pri, c, &req);
789 int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called,
790 int calledplan)
792 struct pri_sr req;
793 if (!pri || !c)
794 return -1;
796 pri_sr_init(&req);
797 pri_sr_set_connection_call_independent(&req);
799 req.caller = caller;
800 req.callerplan = callerplan;
801 req.callername = callername;
802 req.callerpres = callerpres;
803 req.called = called;
804 req.calledplan = calledplan;
806 if(mwi_message_send(pri, c, &req, 0) < 0) {
807 pri_message(pri, "Unable to send MWI deactivate message\n");
808 return -1;
811 return q931_setup(pri, c, &req);
814 int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
816 if (!pri || !c)
817 return -1;
819 return q931_setup(pri, c, req);
822 int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
823 int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called,
824 int calledplan,int ulayer1)
826 struct pri_sr req;
827 if (!pri || !c)
828 return -1;
829 pri_sr_init(&req);
830 req.transmode = transmode;
831 req.channel = channel;
832 req.exclusive = exclusive;
833 req.nonisdn = nonisdn;
834 req.caller = caller;
835 req.callerplan = callerplan;
836 req.callername = callername;
837 req.callerpres = callerpres;
838 req.called = called;
839 req.calledplan = calledplan;
840 req.userl1 = ulayer1;
841 return q931_setup(pri, c, &req);
844 static void (*__pri_error)(char *stuff,int span);
845 static void (*__pri_message)(char *stuff,int span);
847 void pri_set_message(void (*func)(char *stuff,int span))
849 __pri_message = func;
852 void pri_set_error(void (*func)(char *stuff,int span))
854 __pri_error = func;
857 void pri_message(struct pri *pri, char *fmt, ...)
859 char tmp[1024];
860 va_list ap;
861 va_start(ap, fmt);
862 vsnprintf(tmp, sizeof(tmp), fmt, ap);
863 va_end(ap);
864 if (__pri_message && pri) {
865 if (pri->debugfd >= 0)
866 write(pri->debugfd, tmp, strlen(tmp));
867 else
868 __pri_message(tmp, pri->span);
869 } else {
870 fputs(tmp, stdout);
874 void pri_error(struct pri *pri, char *fmt, ...)
876 char tmp[1024];
877 va_list ap;
878 va_start(ap, fmt);
879 vsnprintf(tmp, sizeof(tmp), fmt, ap);
880 va_end(ap);
881 if (__pri_error && pri) {
882 if (pri->debugfd >= 0)
883 write(pri->debugfd, tmp, strlen(tmp));
884 else
885 __pri_error(tmp, pri->span);
886 } else {
887 fputs(tmp, stderr);
891 /* Set overlap mode */
892 void pri_set_overlapdial(struct pri *pri,int state)
894 pri->overlapdial = state;
897 void pri_set_inbanddisconnect(struct pri *pri, unsigned int enable)
899 pri->acceptinbanddisconnect = (enable != 0);
902 int pri_fd(struct pri *pri)
904 return pri->fd;
907 char *pri_dump_info_str(struct pri *pri)
909 char buf[4096];
910 int len = 0;
911 #ifdef LIBPRI_COUNTERS
912 struct q921_frame *f;
913 int q921outstanding = 0;
914 #endif
915 if (!pri)
916 return NULL;
918 /* Might be nice to format these a little better */
919 len += sprintf(buf + len, "Switchtype: %s\n", pri_switch2str(pri->switchtype));
920 len += sprintf(buf + len, "Type: %s\n", pri_node2str(pri->localtype));
921 #ifdef LIBPRI_COUNTERS
922 /* Remember that Q921 Counters include Q931 packets (and any retransmissions) */
923 len += sprintf(buf + len, "Q931 RX: %d\n", pri->q931_rxcount);
924 len += sprintf(buf + len, "Q931 TX: %d\n", pri->q931_txcount);
925 len += sprintf(buf + len, "Q921 RX: %d\n", pri->q921_rxcount);
926 len += sprintf(buf + len, "Q921 TX: %d\n", pri->q921_txcount);
927 f = pri->txqueue;
928 while (f) {
929 q921outstanding++;
930 f = f->next;
932 len += sprintf(buf + len, "Q921 Outstanding: %d\n", q921outstanding);
933 #endif
934 if (pri->localtype != BRI_NETWORK_PTMP) {
935 len += sprintf(buf + len, "Window Length: %d/%d\n", pri->windowlen[0], pri->window[0]);
936 len += sprintf(buf + len, "Sentrej: %d\n", pri->sentrej[0]);
937 len += sprintf(buf + len, "SolicitFbit: %d\n", pri->solicitfbit[0]);
938 len += sprintf(buf + len, "Retrans: %d\n", pri->retrans[0]);
939 len += sprintf(buf + len, "Busy: %d\n", pri->busy[0]);
941 len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial);
942 len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]);
943 len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]);
944 len += sprintf(buf + len, "T305 Timer: %d\n", pri->timers[PRI_TIMER_T305]);
945 len += sprintf(buf + len, "T308 Timer: %d\n", pri->timers[PRI_TIMER_T308]);
946 len += sprintf(buf + len, "T309 Timer: %d\n", pri->timers[PRI_TIMER_T309]);
947 len += sprintf(buf + len, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]);
948 len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]);
951 return strdup(buf);
954 int pri_get_crv(struct pri *pri, q931_call *call, int *callmode)
956 return q931_call_getcrv(pri, call, callmode);
959 int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode)
961 return q931_call_setcrv(pri, call, crv, callmode);
964 void pri_enslave(struct pri *master, struct pri *slave)
966 if (master && slave)
967 slave->callpool = &master->localpool;
970 struct pri_sr *pri_sr_new(void)
972 struct pri_sr *req;
973 req = malloc(sizeof(struct pri_sr));
974 if (req)
975 pri_sr_init(req);
976 return req;
979 void pri_sr_free(struct pri_sr *sr)
981 free(sr);
984 int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn)
986 sr->channel = channel;
987 sr->exclusive = exclusive;
988 sr->nonisdn = nonisdn;
989 return 0;
992 int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1, char *llc)
994 sr->transmode = transmode;
995 sr->userl1 = userl1;
996 sr->llc = llc;
997 return 0;
1000 int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int numcomplete)
1002 sr->called = called;
1003 sr->calledplan = calledplan;
1004 sr->numcomplete = numcomplete;
1005 return 0;
1008 int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
1010 sr->caller = caller;
1011 sr->callername = callername;
1012 sr->callerplan = callerplan;
1013 sr->callerpres = callerpres;
1014 return 0;
1017 int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason)
1019 sr->redirectingnum = num;
1020 sr->redirectingplan = plan;
1021 sr->redirectingpres = pres;
1022 sr->redirectingreason = reason;
1023 return 0;
1026 void pri_shutdown(struct pri *pri)
1028 #ifndef LAYER2ALWAYSUP
1029 #ifndef RELAX_TRB
1030 if ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_CPE_PTMP)) {
1031 q921_reset(pri, pri->tei, 1);
1033 #endif
1034 #endif