Compare commits

..

30 Commits
1.4.5 ... 1.2.5

Author SHA1 Message Date
Russell Bryant
cd276878fd importing files for 1.2.5 release
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.2.5@433 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-07-09 21:58:17 +00:00
Russell Bryant
d3d7923a00 Creating tag for the release of libpri-1.2.5
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.2.5@432 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-07-09 21:57:16 +00:00
Matthew Fredrickson
2fa3049e19 Try to send pending facility messages if we receive alerting (for when we don't get proceeding) (#9651)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@426 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-06-19 18:22:33 +00:00
Matthew Fredrickson
165a1190f2 Oops, that should not be on one line
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@423 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-06-06 21:57:15 +00:00
Matthew Fredrickson
a3f9429129 Make sure we only send the NFE when we are talking QSIG
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@415 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-06-06 13:20:05 +00:00
Matthew Fredrickson
26260008d1 Make sure we send DISCONNECT if we reached the active state and a call is disconnected, regardless of cause code.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@389 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2007-01-22 22:20:59 +00:00
Joshua Colp
b5feb47e50 Specify full path to restorecon instead of assuming it will be available from what is in $PATH. (issue #8670 reported by djflux)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@385 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-12-30 19:16:17 +00:00
Matthew Fredrickson
7e04dfc279 Make sure we send any pending facilty APDUs after we get proceeding. (#7551)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@368 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-07-28 14:44:15 +00:00
Russell Bryant
0dcd4a1c1e ensure buffer is initialized (issue #7512, klaus3000)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@360 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-07-12 19:08:31 +00:00
Matthew Fredrickson
3963b924b2 Fix for #7378 (namespace collision)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@358 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-07-07 15:36:50 +00:00
Matthew Fredrickson
725b07229a Minor state fix. (#7269)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@347 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-06-02 16:05:55 +00:00
Matthew Fredrickson
f1bf41b9f3 Fix for 7115 (Don't call pri_message multiple times per line)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@345 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-06-02 14:33:50 +00:00
Matthew Fredrickson
7d1f278dbe Fixes to fill in non-filled fields in libpri. (Issue #7241) Thanks flefoll!
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@342 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-06-01 17:57:03 +00:00
Kevin P. Fleming
33e5d26221 set LDCONFIG_FLAGS for GNU/kFreeBSD as well
use the flags during installation


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@332 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-04-30 15:17:47 +00:00
Matthew Fredrickson
856498556b Make sure we pass the call back in the setup_ack
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@327 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-04-27 16:08:39 +00:00
Matthew Fredrickson
8bf694a4f5 Fix for #6566 (Makefile does not honor DESTDIR)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@323 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-04-04 15:36:04 +00:00
Matthew Fredrickson
ff8098285c Backport of 6480
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@316 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-02-17 18:55:05 +00:00
Matt O'Gorman
67d7e324a1 bug 6500 typo in README.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@311 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-02-15 17:59:38 +00:00
Kevin P. Fleming
7c66b22563 suppress annoying message about unsupported components in facility messages
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@306 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-02-13 23:06:02 +00:00
Russell Bryant
1626cd29b8 remove old ChangeLog ... it will now only be in the tags
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@296 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-01-18 04:53:47 +00:00
Kevin P. Fleming
cbd9c37c29 ensure that user-user info field in call is properly reset when not needed
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@291 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-01-17 13:43:18 +00:00
Matthew Fredrickson
c3854dede0 Backport of doing correct minor numbers to 1.2 (#6188)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@290 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-01-10 20:19:14 +00:00
Matthew Fredrickson
29d1983e4d Fix for issue #6039 backported to 1.2
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@284 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-12-27 14:01:34 +00:00
Matthew Fredrickson
8fc524e6e7 Send RR as command instead of response when T200 expires after receiving RNR.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@280 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-12-06 21:35:50 +00:00
Kevin P. Fleming
50e2d23352 Makefile 'update' target now supports Subversion repositories (issue #5875)
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@274 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-12-01 23:13:49 +00:00
Matthew Fredrickson
8c424cc4ff Backport of fix from trunk. Fix broken single digit keypad facility code.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@270 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-12-01 02:34:44 +00:00
Kevin P. Fleming
2f6aee20d9 remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@266 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 18:39:18 +00:00
Kevin P. Fleming
1328ab60de remove CVS ignore list, update SVN ignore list
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@265 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 00:31:21 +00:00
Kevin P. Fleming
f826a6e4ad rename branches
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.2@261 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-27 04:14:49 +00:00
Admin Commit
4ec90f7435 This commit was manufactured by cvs2svn to create branch 'v1-2'.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/v1-2@256 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-10-25 16:59:59 +00:00
21 changed files with 720 additions and 2939 deletions

View File

@@ -1 +1 @@
1.4.5
1.2.5

317
ChangeLog
View File

@@ -1,303 +1,118 @@
2008-07-11 Jason Parker <jparker@digium.com>
2007-07-09 Russell Bryant <russell@digium.com>
* Libpri 1.4.5 released.
* libpri 1.2.5 Released
2008-07-11 16:44 +0000 [r574-579] Kevin P. Fleming <kpfleming@digium.com>
2007-06-19 18:22 +0000 [r426] Matthew Fredrickson <creslin@digium.com>
* /: ignore generated files
* q931.c: Try to send pending facility messages if we receive
alerting (for when we don't get proceeding) (#9651)
* pri.c, pri_internal.h, q931.c, libpri.h: modify work done for
issue #10552, making the support of inband audio after RELEASE a
configurable option, since it is causing problems for a number of
users (closes issue #13042)
2007-06-06 21:57 +0000 [r415-423] Matthew Fredrickson <creslin@digium.com>
2008-06-04 17:02 +0000 [r562] Dwayne M. Hubbard <dhubbard@digium.com>
* pri_facility.c: Oops, that should not be on one line
* q931.c: While working on issue 3450 I noticed that the
information channel selection field in the channel identification
IE was displayed incorrectly when using 'pri intense debug'. I
wanted another pair of eyes to look at the code because
everything looked correct until Shaun Ruffell noticed the missing
comma in the msg_chan_sel array.
* pri_facility.c: Make sure we only send the NFE when we are
talking QSIG
2008-05-07 19:51 +0000 [r557] Matthew Fredrickson <creslin@digium.com>
2007-01-22 22:20 +0000 [r389] Matthew Fredrickson <creslin@digium.com>
* pri.c, pritest.c, pri_internal.h, pri_q921.h, Makefile, q921.c,
q931.c, pri_facility.c, prisched.c, testprilib.c, pri_timers.h,
pri_facility.h, libpri.h: Moving trunk changes back into 1.4
* q931.c: Make sure we send DISCONNECT if we reached the active
state and a call is disconnected, regardless of cause code.
2008-05-07 Matthew Fredrickson <creslin@digium.com>
2006-12-30 19:16 +0000 [r385] Joshua Colp <jcolp@digium.com>
* Libpri 1.4.4 released.
* Makefile: Specify full path to restorecon instead of assuming it
will be available from what is in $PATH. (issue #8670 reported by
djflux)
2008-05-06 16:43 +0000 [r553-555] Matthew Fredrickson <creslin@digium.com>
2006-10-17 Kevin P. Fleming <kpfleming@digium.com>
* q921.c, pri.c: Remove some unnecessary debug messages
* libpri 1.2.4 Released
* q931.c: We passed TBR3 layer 2 and layer 3 testing with this
commit in for BRI-TE PTMP.
2006-07-28 14:44 +0000 [r368] Matt Frederickson <creslin@digium.com>
* q931.c: Final patch to pass certification
* q931.c: Make sure we send any pending facilty APDUs after we get
proceeding. (#7551)
2008-04-22 15:30 +0000 [r546] Russell Bryant <russell@digium.com>
2006-07-12 19:08 +0000 [r360] Russell Bryant <russell@digium.com>
* Makefile: All versions of libpri have been installed as
libpri.so.1.0, even though the API and ABI have changed over
time. This patch changes the Makefile to install the library as
libpri.so.1.4 to indicate that this is not compatible with
previous versions. In the future, this should be changed as we
make ABI changes. (closes issue #10376) Reported by: tzafrir
Patches: libpri-soname.diff uploaded by tzafrir (license 46) --
with very minor changes by me
* q931.c: ensure buffer is initialized (issue #7512, klaus3000)
2008-03-15 19:57 +0000 [r541-543] Matthew Fredrickson <creslin@digium.com>
2006-07-07 15:36 +0000 [r358] Matt Frederickson <creslin@digium.com>
* libpri.h, pri.c: Remove some useless event items
* q931.c: Fix for #7378 (namespace collision)
* q921.c, pri_internal.h: Make sure if we're a bri and in PTMP mode
that we release the TEI and try to get a new one with the other
end when we lose activity in multiframe mode
2006-06-02 16:05 +0000 [r342-347] Matt Frederickson <creslin@digium.com>
* q921.c, pri.c, pri_q921.h: When we recieve a UA in any TEI
established state other than awaiting establishement make sure we
drop the TEI and get a new one. For passing tests PC37.2 - PC41.2
in Q.921
* q931.c: Minor state fix. (#7269)
2008-03-06 23:43 +0000 [r538-539] Matthew Fredrickson <creslin@digium.com>
* q931.c: Fix for 7115 (Don't call pri_message multiple times per
line)
* q921.c: Make sure we are sending as command not as response
* q931.c: Fixes to fill in non-filled fields in libpri. (Issue
#7241) Thanks flefoll!
* q921.c: Make sure C/R bit is correct
2006-05-30 Kevin P. Fleming <kpfleming@digium.com>
2008-03-01 23:30 +0000 [r531-535] Matthew Fredrickson <creslin@digium.com>
* libpri 1.2.3 Released
* q921.c: Remove some (currently) useless code
2006-04-30 15:17 +0000 [r332] Kevin P. Fleming <kpfleming@digium.com>
* q921.c, pri.c, pri_internal.h: Some more updates to add code for
passing PC 27.1 in Q.921
* Makefile: set LDCONFIG_FLAGS for GNU/kFreeBSD as well use the
flags during installation
* q921.c, pri.c: Various coding style cleanups as well as a bug fix
for TEI removal
2006-04-27 16:08 +0000 [r327] Matt Frederickson <creslin@digium.com>
* q921.c, q931.c, pri.c, pri_internal.h: Initial checkin of code to
pass Q.921 PC25 and PC26
* q931.c, libpri.h: Make sure we pass the call back in the
setup_ack
* q921.c: Add support for responding to TEI requests (Q.921 PC23.x)
2006-04-04 15:36 +0000 [r323] Matt Frederickson <creslin@digium.com>
2008-02-18 20:31 +0000 [r525] Matthew Fredrickson <creslin@digium.com>
* Makefile: Fix for #6566 (Makefile does not honor DESTDIR)
* q931.c, libpri.h: Improve transmission, receiving, and dumping of
bearer capability IE (#11593)
2006-02-17 18:55 +0000 [r316] Matt Frederickson <creslin@digium.com>
2008-01-16 18:06 +0000 [r518] Jason Parker <jparker@digium.com>
* q931.c: Backport of 6480
* Makefile, /: Add logging for 'make update' command (also fixes
updates in some places). Issue #11766, initial patch by jmls.
2006-02-15 17:59 +0000 [r311] Matt O'Gorman <mogorman@digium.com>
2007-12-26 17:35 +0000 [r505] Russell Bryant <russell@digium.com>
* README: bug 6500 typo in README.
* libpri.h: Remove unnecessary usage of the extern keyword.
2006-02-13 23:06 +0000 [r306] Kevin P. Fleming <kpfleming@digium.com>
2007-12-06 22:16 +0000 [r494-496] Russell Bryant <russell@digium.com>
* pri_facility.c: suppress annoying message about unsupported
components in facility messages
* q921.c, q931.c, pri_facility.c, pri.c: Change malloc+memset to
calloc. Also, handle allocation failures early to reduce
indentation. (closes issue #11469) Reported by: eliel Patches:
pri.c.patch uploaded by eliel (license 64) q931.c.patch uploaded
by eliel (license 64) q921.c.patch uploaded by eliel (license 64)
pri_facility.c.patch uploaded by eliel (license 64)
2006-01-18 Russell Bryant <russell@digium.com>
* pri.c: Change a use of malloc+memset to calloc. Also, reduce
indentation of a function by doing the check for memory
allocation failure at the beginning.
* Libpri 1.2.2 Released
* pri.c: Change the table used to hold the default timers to be
global and const, instead of allocating it on the stack each time
the function is called.
2006-01-17 13:43 +0000 [r291] Kevin P. Fleming <kpfleming@digium.com>
2007-12-05 00:20 +0000 [r491-493] Matthew Fredrickson <creslin@digium.com>
* q931.c: ensure that user-user info field in call is properly
reset when not needed
* q931.c: Improve the parameter name to better reflect its use
2006-01-10 20:19 +0000 [r290] Matt Frederickson <creslin@digium.com>
* q921.c, q931.c: More PTMP fixes. Stand by, more changes to come
* Makefile: Backport of doing correct minor numbers to 1.2 (#6188)
* q921.c, q931.c, testprilib.c: More magic to make BRI CPE PTMP
work
2005-12-27 14:01 +0000 [r284] Matt Frederickson <creslin@digium.com>
2007-11-21 22:30 +0000 [r486-487] Matthew Fredrickson <creslin@digium.com>
* q931.c: Fix for issue #6039 backported to 1.2
* q931.c: Make sure we loop BRI call references for one byte CREFs
instead of two
2005-12-06 21:35 +0000 [r280] Matt Frederickson <creslin@digium.com>
* q921.c, q931.c, libpri.h, pri.c, pritest.c, pri_internal.h: Add
BRI support to libpri
* q921.c: Send RR as command instead of response when T200 expires
after receiving RNR.
2007-10-13 16:00 +0000 [r473] Matthew Fredrickson <creslin@digium.com>
2005-12-01 23:13 +0000 [r274] Kevin P. Fleming <kpfleming@digium.com>
* q921.c: Make sure that we only output the message handling debug
when we're actually debugging
* Makefile: Makefile 'update' target now supports Subversion
repositories (issue #5875)
2007-09-25 21:56 +0000 [r469] Matthew Fredrickson <creslin@digium.com>
2005-12-01 02:34 +0000 [r270] Matt Frederickson <creslin@digium.com>
* q931.c: Fix user-user IE order in setup message (#10705)
* q931.c: Backport of fix from trunk. Fix broken single digit
keypad facility code.
2007-06-20 15:18 +0000 [r428-430] Matthew Fredrickson <creslin@digium.com>
* Makefile: Revert that back to how it was
* Makefile, q921.c, q931.c, prisched.c, testprilib.c, pri_timers.h,
libpri.h, pri.c, pri_internal.h, pri_q921.h: Patch to add PTMP
mode (BRI support)
2007-06-06 21:59 +0000 [r417-425] Matthew Fredrickson <creslin@digium.com>
* q931.c, pri_facility.c, pri_facility.h, pri.c, pri_internal.h:
Preliminary patch plus mods for Q.SIG Path Replacement (Q.SIG
version of 2BCT) #7778
2007-05-25 17:36 +0000 [r413] Matthew Fredrickson <creslin@digium.com>
* q931.c, pri_facility.c, pri_facility.h, libpri.h: Commit path for
ROSE-12 and ROSE-13 support (#9076)
2006-11-03 18:16 +0000 [r382] Matthew Fredrickson <creslin@digium.com>
* q921.c: Remove pointless recursion. (#8281)
2008-05-07 19:51 +0000 [r557] Matthew Fredrickson <creslin@digium.com>
* pri.c, pritest.c, pri_internal.h, pri_q921.h, Makefile, q921.c,
q931.c, pri_facility.c, prisched.c, testprilib.c, pri_timers.h,
pri_facility.h, libpri.h: Moving trunk changes back into 1.4
2008-05-02 20:21 +0000 [r552] Brett Bryant <bbryant@digium.com>
* Makefile, build_tools (added), build_tools/make_version (added),
build_tools/make_version_c (added), libpri.h: Add new API call
(pri_get_version) to show the current version of the branch for
support purposes.
2008-04-16 00:21 +0000 [r544] Kevin P. Fleming <kpfleming@digium.com>
* q921.c: fix the indentation in this function so that it is
actually possible to read it and understand the logic and flow
2008-02-21 16:38 +0000 [r528] Joshua Colp <jcolp@digium.com>
* q931.c: If inband audio is being provided with a disconnect
message let the audio be heard before releasing the channel.
(closes issue #10552) Reported by: paravoid Patches:
disconnect-audio.diff uploaded by paravoid (license 200)
2008-02-18 20:31 +0000 [r524] Matthew Fredrickson <creslin@digium.com>
* q931.c, libpri.h: Improve transmission, receiving, and dumping of
bearer capability IE (#11593)
2008-01-11 16:34 +0000 [r514] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 513 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r513
| mattf | 2008-01-11 10:33:52 -0600 (Fri, 11 Jan 2008) | 1 line
We should not be parsing further into the bearer capability IE if
the length does not confirm that there actually is data present
........
2007-12-13 Russell Bryant <russell@digium.com>
* libpri 1.4.3 released.
2007-10-22 15:10 +0000 [r479] Kevin P. Fleming <kpfleming@digium.com>
* pri_internal.h, /: Merged revisions 478 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r478
| kpfleming | 2007-10-22 10:09:27 -0500 (Mon, 22 Oct 2007) | 3
lines we need to include stddef.h for 'size_t' ........
2007-10-16 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.2 released.
2007-10-05 16:45 +0000 [r470] Jason Parker <jparker@digium.com>
* libpri.h: Fix an incorrect pri_event structure definition. Issue
10832, patch by flefoll
2007-09-25 21:37 +0000 [r468] Matthew Fredrickson <creslin@digium.com>
* q931.c: Fix user-user IE order in setup message (#10705)
2007-09-14 21:32 +0000 [r465] Matthew Fredrickson <creslin@digium.com>
* q931.c, libpri.h: Fix for #10189. Make sure we properly report
the user layer 1 for H.223 and H.245
2007-09-06 15:11 +0000 [r462] Matthew Fredrickson <creslin@digium.com>
* pri.c, pri_facility.c, /: Merged revisions 460 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r460
| mattf | 2007-09-06 10:06:42 -0500 (Thu, 06 Sep 2007) | 1 line
TBCT now works. It should work for NI2, 4E, and 5E. This code was
tested on NI2. ........
2007-08-27 19:21 +0000 [r446] Jason Parker <jparker@digium.com>
* Makefile, /: Merged revisions 445 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r445
| qwell | 2007-08-27 14:20:23 -0500 (Mon, 27 Aug 2007) | 2 lines
Make sure we build both the static and shared modules with -fPIC.
........
2007-08-06 19:58 +0000 [r441] Jason Parker <jparker@digium.com>
* Makefile: Allow setting CC to something with a space, such as
`make CC="gcc -m32"` Issue 10253.
2007-07-09 Russell Bryant <russell@digium.com>
* libpri 1.4.1 released.
2007-06-19 18:23 +0000 [r427] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 426 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r426
| mattf | 2007-06-19 13:22:33 -0500 (Tue, 19 Jun 2007) | 1 line
Try to send pending facility messages if we receive alerting (for
when we don't get proceeding) (#9651) ........
2007-06-06 21:58 +0000 [r416-424] Matthew Fredrickson <creslin@digium.com>
* pri_facility.c, /: Merged revisions 423 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r423
| mattf | 2007-06-06 16:57:15 -0500 (Wed, 06 Jun 2007) | 1 line
Oops, that should not be on one line ........
* pri_facility.c, /: Merged revisions 415 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r415
| mattf | 2007-06-06 08:20:05 -0500 (Wed, 06 Jun 2007) | 2 lines
Make sure we only send the NFE when we are talking QSIG ........
2007-01-22 22:29 +0000 [r390] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 389 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r389
| mattf | 2007-01-22 16:20:59 -0600 (Mon, 22 Jan 2007) | 2 lines
Make sure we send DISCONNECT if we reached the active state and a
call is disconnected, regardless of cause code. ........
2006-12-30 19:17 +0000 [r386] Joshua Colp <jcolp@digium.com>
* Makefile, /: Merged revisions 385 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r385
| file | 2006-12-30 14:16:17 -0500 (Sat, 30 Dec 2006) | 2 lines
Specify full path to restorecon instead of assuming it will be
available from what is in $PATH. (issue #8670 reported by djflux)
........
2006-12-23 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.0 released.
2006-09-20 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.0-beta1 released.

View File

@@ -28,46 +28,37 @@
#LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
CC=gcc
GREP=grep
AWK=awk
OSARCH=$(shell uname -s)
PROC?=$(shell uname -m)
# SONAME version; should be changed on every ABI change
# please don't change it needlessly; it's perfectly fine to have a SONAME
# of 1.2 and a version of 1.4.x
SONAME:=1.4
TOBJS=testpri.o
T2OBJS=testprilib.o
STATIC_LIBRARY=libpri.a
DYNAMIC_LIBRARY:=libpri.so.$(SONAME)
STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o version.o
DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo version.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS)
DYNAMIC_LIBRARY=libpri.so.1.0
STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o
DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
INSTALL_PREFIX=$(DESTDIR)
INSTALL_BASE=/usr
SOFLAGS:=-Wl,-h$(DYNAMIC_LIBRARY)
SOFLAGS = -Wl,-hlibpri.so.1.0
LDCONFIG = /sbin/ldconfig
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX))
ifneq (,$(findstring $(OSARCH), Linux GNU/kFreeBSD))
LDCONFIG_FLAGS=-n
else
ifeq (${OSARCH},FreeBSD)
LDCONFIG_FLAGS=-m
CFLAGS += -I../zaptel -I../zapata
INSTALL_BASE=/usr/local
endif
endif
ifeq (${OSARCH},SunOS)
CFLAGS += -DSOLARIS -I../zaptel-solaris
LDCONFIG =
LDCONFIG_FLAGS = \# # Trick to comment out the period in the command below
SOSLINK = ln -sf libpri.so.1.0 libpri.so.1
#INSTALL_PREFIX = /opt/asterisk # Uncomment out to install in standard Solaris location for 3rd party code
endif
export PRIVERSION
PRIVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) build_tools/make_version .)
#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
#This works for even old (2.96) versions of gcc and provides a small boost either way.
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesnt support it.
@@ -81,16 +72,10 @@ all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
update:
@if [ -d .svn ]; then \
echo "Updating from Subversion..." ; \
fromrev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
svn update | tee update.out; \
torev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
echo "`date` Updated from revision $${fromrev} to $${torev}." >> update.log; \
rm -f .version; \
if [ `grep -c ^C update.out` -gt 0 ]; then \
echo ; echo "The following files have conflicts:" ; \
grep ^C update.out | cut -b4- ; \
fi ; \
rm -f update.out; \
svn update -q; \
elif [ -d CVS ]; then \
echo "Updating from CVS..." ; \
cvs -q -z3 update -Pd; \
else \
echo "Not under version control"; \
fi
@@ -102,19 +87,20 @@ ifneq (${OSARCH},SunOS)
install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.1.0 libpri.so ; ln -sf libpri.so.1.0 libpri.so.1 )
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib; fi
else
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.1.0 libpri.so ; $(SOSLINK) )
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 644 $(STATIC_LIBRARY)
endif
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.1.0
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.1
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.a
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
@@ -136,7 +122,7 @@ include .depend
endif
%.lo : %.c
$(CC) $(CFLAGS) -o $@ -c $<
$(CC) -fPIC $(CFLAGS) -o $@ -c $<
$(STATIC_LIBRARY): $(STATIC_OBJS)
ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
@@ -145,22 +131,17 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
$(LDCONFIG) $(LDCONFIG_FLAGS) .
ln -sf libpri.so.$(SONAME) libpri.so
version.c:
@build_tools/make_version_c > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
ln -sf libpri.so.1.0 libpri.so
ln -sf libpri.so.1.0 libpri.so.1
$(SOSLINK)
clean:
rm -f *.o *.so *.lo *.so.$(SONAME)
rm -f testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f *.o *.so *.lo *.so.1 *.so.1.0
rm -f testpri testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f pritest pridump
rm -f .depend
depend: .depend
.depend:
CC="$(CC)" ./mkdep ${CFLAGS} `ls *.c`
.PHONY: version.c
CC=$(CC) ./mkdep ${CFLAGS} `ls *.c`

4
TODO
View File

@@ -1,8 +1,10 @@
General:
-- D-Channel Backup
-- Test against 4e
Q.921:
-- Support unnumbered information frames
-- Get TEI codes working for BRI interfaces
Q.931:
-- Locking Shift IE
-- Implement the 11 missing Q.931 timers

View File

@@ -1,74 +0,0 @@
#!/bin/sh
if [ -f ${1}/.version ]; then
cat ${1}/.version
elif [ -d .svn ]; then
PARTS=`LANG=C svn info ${1} | ${GREP} URL | ${AWK} '{print $2;}' | sed -e 's:^.*/svn/libpri/::' | sed -e 's:/: :g'`
BRANCH=0
TEAM=0
TAG=0
REV=`svnversion -c ${1} | cut -d: -f2`
BASE=`LANG=C svn pg svnmerge-integrated ${1} | cut -d: -f1`
if [ "${PARTS}" = "trunk" ] ; then
echo SVN-trunk-r${REV}
exit 0
fi
for PART in $PARTS ; do
if [ ${TAG} != 0 ] ; then
if [ "${PART}" = "autotag_for_be" ] ; then
continue
fi
if [ "${PART}" = "autotag_for_sx00i" ] ; then
continue
fi
RESULT="${PART}"
break
fi
if [ ${BRANCH} != 0 ] ; then
if [ -z ${RESULT} ] ; then
RESULT="2${PART}"
else
RESULT="3${RESULT}-${PART}"
fi
break
fi
if [ ${TEAM} != 0 ] ; then
if [ -z ${RESULT} ] ; then
RESULT="4${PART}"
else
RESULT="5${RESULT}-${PART}"
fi
continue
fi
if [ "${PART}" = "branches" ] ; then
BRANCH=1
RESULT="branch"
continue
fi
if [ "${PART}" = "tags" ] ; then
TAG=1
continue
fi
if [ "${PART}" = "team" ] ; then
TEAM=1
continue
fi
done
RESULT="libss7"
if [ ${TAG} != 0 ] ; then
echo ${RESULT}
else
echo SVN-${RESULT}-r${REV}${BASE:+-${BASE}}
fi
fi

View File

@@ -1,24 +0,0 @@
#!/bin/sh
if [ ! -f ../.flavor ]; then
EXTRA=""
else
aadkver=`cat ../.version`
aadkflavor=`cat ../.flavor`
EXTRA=" (${aadkflavor} ${aadkver})"
fi
cat << END
/*
* version.c
* Automatically generated
*/
#include "libpri.h"
static const char pri_version[] = "${PRIVERSION}${EXTRA}";
const char *pri_get_version(void)
{
return pri_version;
}
END

209
libpri.h
View File

@@ -142,10 +142,10 @@
/* Causes for disconnection */
#define PRI_CAUSE_UNALLOCATED 1
#define PRI_CAUSE_NO_ROUTE_TRANSIT_NET 2 /* !Q.SIG */
#define PRI_CAUSE_NO_ROUTE_TRANSIT_NET 2
#define PRI_CAUSE_NO_ROUTE_DESTINATION 3
#define PRI_CAUSE_CHANNEL_UNACCEPTABLE 6
#define PRI_CAUSE_CALL_AWARDED_DELIVERED 7 /* !Q.SIG */
#define PRI_CAUSE_CALL_AWARDED_DELIVERED 7
#define PRI_CAUSE_NORMAL_CLEARING 16
#define PRI_CAUSE_USER_BUSY 17
#define PRI_CAUSE_NO_USER_RESPONSE 18
@@ -154,29 +154,27 @@
#define PRI_CAUSE_NUMBER_CHANGED 22
#define PRI_CAUSE_DESTINATION_OUT_OF_ORDER 27
#define PRI_CAUSE_INVALID_NUMBER_FORMAT 28
#define PRI_CAUSE_FACILITY_REJECTED 29 /* !Q.SIG */
#define PRI_CAUSE_FACILITY_REJECTED 29
#define PRI_CAUSE_RESPONSE_TO_STATUS_ENQUIRY 30
#define PRI_CAUSE_NORMAL_UNSPECIFIED 31
#define PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION 34
#define PRI_CAUSE_NETWORK_OUT_OF_ORDER 38 /* !Q.SIG */
#define PRI_CAUSE_NETWORK_OUT_OF_ORDER 38
#define PRI_CAUSE_NORMAL_TEMPORARY_FAILURE 41
#define PRI_CAUSE_SWITCH_CONGESTION 42 /* !Q.SIG */
#define PRI_CAUSE_ACCESS_INFO_DISCARDED 43 /* !Q.SIG */
#define PRI_CAUSE_SWITCH_CONGESTION 42
#define PRI_CAUSE_ACCESS_INFO_DISCARDED 43
#define PRI_CAUSE_REQUESTED_CHAN_UNAVAIL 44
#define PRI_CAUSE_PRE_EMPTED 45 /* !Q.SIG */
#define PRI_CAUSE_FACILITY_NOT_SUBSCRIBED 50 /* !Q.SIG */
#define PRI_CAUSE_OUTGOING_CALL_BARRED 52 /* !Q.SIG */
#define PRI_CAUSE_INCOMING_CALL_BARRED 54 /* !Q.SIG */
#define PRI_CAUSE_PRE_EMPTED 45
#define PRI_CAUSE_FACILITY_NOT_SUBSCRIBED 50
#define PRI_CAUSE_OUTGOING_CALL_BARRED 52
#define PRI_CAUSE_INCOMING_CALL_BARRED 54
#define PRI_CAUSE_BEARERCAPABILITY_NOTAUTH 57
#define PRI_CAUSE_BEARERCAPABILITY_NOTAVAIL 58
#define PRI_CAUSE_SERVICEOROPTION_NOTAVAIL 63 /* Q.SIG */
#define PRI_CAUSE_BEARERCAPABILITY_NOTIMPL 65
#define PRI_CAUSE_CHAN_NOT_IMPLEMENTED 66 /* !Q.SIG */
#define PRI_CAUSE_FACILITY_NOT_IMPLEMENTED 69 /* !Q.SIG */
#define PRI_CAUSE_CHAN_NOT_IMPLEMENTED 66
#define PRI_CAUSE_FACILITY_NOT_IMPLEMENTED 69
#define PRI_CAUSE_INVALID_CALL_REFERENCE 81
#define PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST 82 /* Q.SIG */
#define PRI_CAUSE_INCOMPATIBLE_DESTINATION 88
#define PRI_CAUSE_INVALID_MSG_UNSPECIFIED 95 /* !Q.SIG */
#define PRI_CAUSE_INVALID_MSG_UNSPECIFIED 95
#define PRI_CAUSE_MANDATORY_IE_MISSING 96
#define PRI_CAUSE_MESSAGE_TYPE_NONEXIST 97
#define PRI_CAUSE_WRONG_MESSAGE 98
@@ -184,9 +182,9 @@
#define PRI_CAUSE_INVALID_IE_CONTENTS 100
#define PRI_CAUSE_WRONG_CALL_STATE 101
#define PRI_CAUSE_RECOVERY_ON_TIMER_EXPIRE 102
#define PRI_CAUSE_MANDATORY_IE_LENGTH_ERROR 103 /* !Q.SIG */
#define PRI_CAUSE_MANDATORY_IE_LENGTH_ERROR 103
#define PRI_CAUSE_PROTOCOL_ERROR 111
#define PRI_CAUSE_INTERWORKING 127 /* !Q.SIG */
#define PRI_CAUSE_INTERWORKING 127
/* Transmit capabilities */
#define PRI_TRANS_CAP_SPEECH 0x0
@@ -202,57 +200,11 @@
#define PRI_LAYER_1_ALAW 0x23
#define PRI_LAYER_1_G721 0x24
#define PRI_LAYER_1_G722_G725 0x25
#define PRI_LAYER_1_H223_H245 0x26
#define PRI_LAYER_1_G7XX_384K 0x26
#define PRI_LAYER_1_NON_ITU_ADAPT 0x27
#define PRI_LAYER_1_V120_RATE_ADAPT 0x28
#define PRI_LAYER_1_X31_RATE_ADAPT 0x29
/* Intermediate rates for V.110 */
#define PRI_INT_RATE_8K 1
#define PRI_INT_RATE_16K 2
#define PRI_INT_RATE_32K 3
/* Rate adaption for bottom 5 bits of rateadaption */
#define PRI_RATE_USER_RATE_MASK 0x1F
#define PRI_RATE_ADAPT_UNSPEC 0x00
#define PRI_RATE_ADAPT_0K6 0x01
#define PRI_RATE_ADAPT_1K2 0x02
#define PRI_RATE_ADAPT_2K4 0x03
#define PRI_RATE_ADAPT_3K6 0x04
#define PRI_RATE_ADAPT_4K8 0x05
#define PRI_RATE_ADAPT_7K2 0x06
#define PRI_RATE_ADAPT_8K 0x07
#define PRI_RATE_ADAPT_9K6 0x08
#define PRI_RATE_ADAPT_14K4 0x09
#define PRI_RATE_ADAPT_16K 0x0A
#define PRI_RATE_ADAPT_19K2 0x0B
#define PRI_RATE_ADAPT_32K 0x0C
#define PRI_RATE_ADAPT_38K4 0x0D
#define PRI_RATE_ADAPT_48K 0x0E
#define PRI_RATE_ADAPT_56K 0x0F
#define PRI_RATE_ADAPT_57K6 0x12
#define PRI_RATE_ADAPT_28K8 0x13
#define PRI_RATE_ADAPT_24K 0x14
#define PRI_RATE_ADAPT_0K1345 0x15
#define PRI_RATE_ADAPT_0K1 0x16
#define PRI_RATE_ADAPT_0K075_1K2 0x17
#define PRI_RATE_ADAPT_1K2_0K075 0x18
#define PRI_RATE_ADAPT_0K05 0x19
#define PRI_RATE_ADAPT_0K075 0x1A
#define PRI_RATE_ADAPT_0K110 0x1B
#define PRI_RATE_ADAPT_0K150 0x1C
#define PRI_RATE_ADAPT_0K200 0x1D
#define PRI_RATE_ADAPT_0K300 0x1E
#define PRI_RATE_ADAPT_12K 0x1F
/* in-band negotiation flag for rateadaption bit 5 */
#define PRI_RATE_ADAPT_NEGOTIATION_POSS 0x20
/* async flag for rateadaption bit 6 */
#define PRI_RATE_ADAPT_ASYNC 0x40
/* Notifications */
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
@@ -342,8 +294,6 @@ typedef struct pri_event_facname {
int channel;
int cref;
q931_call *call;
int callingpres; /* Presentation of Calling CallerID */
int callingplan; /* Dialing plan of Calling entity */
} pri_event_facname;
#define PRI_CALLINGPLANANI
@@ -434,7 +384,7 @@ typedef union {
pri_event_ring ring; /* Ring */
pri_event_hangup hangup; /* Hang up */
pri_event_ringing ringing; /* Ringing */
pri_event_answer answer; /* Answer */
pri_event_ringing answer; /* Answer */
pri_event_restart_ack restartack; /* Restart Acknowledge */
pri_event_proceeding proceeding; /* Call proceeding & Progress */
pri_event_setup_ack setup_ack; /* SETUP_ACKNOWLEDGE structure */
@@ -453,78 +403,73 @@ typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen);
channel operating in HDLC mode with FCS computed by the fd's driver. Also it
must be NON-BLOCKING! Frames received on the fd should include FCS. Nodetype
must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */
struct pri *pri_new(int fd, int nodetype, int switchtype);
struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype);
extern struct pri *pri_new(int fd, int nodetype, int switchtype);
/* Create D-channel just as above with user defined I/O callbacks and data */
struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
/* Retrieve the user data associated with the D channel */
void *pri_get_userdata(struct pri *pri);
extern void *pri_get_userdata(struct pri *pri);
/* Set the user data associated with the D channel */
void pri_set_userdata(struct pri *pri, void *userdata);
extern void pri_set_userdata(struct pri *pri, void *userdata);
/* Set Network Specific Facility for PRI */
void pri_set_nsf(struct pri *pri, int nsf);
extern void pri_set_nsf(struct pri *pri, int nsf);
/* Set debug parameters on PRI -- see above debug definitions */
void pri_set_debug(struct pri *pri, int debug);
extern void pri_set_debug(struct pri *pri, int debug);
/* Get debug parameters on PRI -- see above debug definitions */
int pri_get_debug(struct pri *pri);
extern int pri_get_debug(struct pri *pri);
#define PRI_FACILITY_ENABLE
/* Enable transmission support of Facility IEs on the pri */
void pri_facility_enable(struct pri *pri);
extern void pri_facility_enable(struct pri *pri);
/* Run PRI on the given D-channel, taking care of any events that
need to be handled. If block is set, it will block until an event
occurs which needs to be handled */
pri_event *pri_dchannel_run(struct pri *pri, int block);
extern pri_event *pri_dchannel_run(struct pri *pri, int block);
/* Check for an outstanding event on the PRI */
pri_event *pri_check_event(struct pri *pri);
/* Give a name to a given event ID */
char *pri_event2str(int id);
extern char *pri_event2str(int id);
/* Give a name to a node type */
char *pri_node2str(int id);
extern char *pri_node2str(int id);
/* Give a name to a switch type */
char *pri_switch2str(int id);
extern char *pri_switch2str(int id);
/* Print an event */
void pri_dump_event(struct pri *pri, pri_event *e);
extern void pri_dump_event(struct pri *pri, pri_event *e);
/* Turn presentation into a string */
char *pri_pres2str(int pres);
extern char *pri_pres2str(int pres);
/* Turn numbering plan into a string */
char *pri_plan2str(int plan);
extern char *pri_plan2str(int plan);
/* Turn cause into a string */
char *pri_cause2str(int cause);
extern char *pri_cause2str(int cause);
/* Acknowledge a call and place it on the given channel. Set info to non-zero if there
is in-band data available on the channel */
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
extern int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
/* Send a digit in overlap mode */
int pri_information(struct pri *pri, q931_call *call, char digit);
#define PRI_KEYPAD_FACILITY_TX
/* Send a keypad facility string of digits */
int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits);
extern int pri_information(struct pri *pri, q931_call *call, char digit);
/* Answer the incomplete(call without called number) call on the given channel.
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
/* Answer the call on the given channel (ignored if you called acknowledge already).
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
/* Set CRV reference for GR-303 calls */
@@ -541,60 +486,59 @@ int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
/* Hangup a call */
#define PRI_HANGUP
int pri_hangup(struct pri *pri, q931_call *call, int cause);
extern int pri_hangup(struct pri *pri, q931_call *call, int cause);
#define PRI_DESTROYCALL
void pri_destroycall(struct pri *pri, q931_call *call);
extern void pri_destroycall(struct pri *pri, q931_call *call);
#define PRI_RESTART
int pri_restart(struct pri *pri);
extern int pri_restart(struct pri *pri);
int pri_reset(struct pri *pri, int channel);
extern int pri_reset(struct pri *pri, int channel);
/* Create a new call */
q931_call *pri_new_call(struct pri *pri);
extern q931_call *pri_new_call(struct pri *pri);
/* Retrieve CRV reference for GR-303 calls. Returns >0 on success. */
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
extern int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
/* Retrieve CRV reference for GR-303 calls. CRV must be >0, call mode should be 0 */
int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode);
extern int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode);
/* How long until you need to poll for a new event */
struct timeval *pri_schedule_next(struct pri *pri);
extern struct timeval *pri_schedule_next(struct pri *pri);
/* Run any pending schedule events */
extern pri_event *pri_schedule_run(struct pri *pri);
extern pri_event *pri_schedule_run_tv(struct pri *pri, const struct timeval *now);
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
extern int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
char *called,int calledplan, int ulayer1);
struct pri_sr *pri_sr_new(void);
void pri_sr_free(struct pri_sr *sr);
extern struct pri_sr *pri_sr_new(void);
extern void pri_sr_free(struct pri_sr *sr);
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
#define PRI_USER_USER_TX
/* Set the user user field. Warning! don't send binary data accross this field */
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);
extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars);
void pri_call_set_useruser(q931_call *sr, const char *userchars);
extern void pri_call_set_useruser(q931_call *sr, char *userchars);
int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
/* Set a call has a call indpendent signalling connection (i.e. no bchan) */
int pri_sr_set_connection_call_independent(struct pri_sr *req);
extern int pri_sr_set_connection_call_independent(struct pri_sr *req);
/* Send an MWI indication to a remote location. If activate is non zero, activates, if zero, decativates */
int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
extern int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
/* Send an MWI deactivate request to a remote location */
int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
extern int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
#define PRI_2BCT
/* Attempt to pass the channels back to the NET side if compatable and
@@ -603,33 +547,30 @@ int pri_channel_bridge(q931_call *call1, q931_call *call2);
/* Override message and error stuff */
#define PRI_NEW_SET_API
void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
extern void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
extern void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
/* Set overlap mode */
#define PRI_SET_OVERLAPDIAL
void pri_set_overlapdial(struct pri *pri,int state);
extern void pri_set_overlapdial(struct pri *pri,int state);
#define PRI_DUMP_INFO_STR
char *pri_dump_info_str(struct pri *pri);
extern char *pri_dump_info_str(struct pri *pri);
/* Get file descriptor */
int pri_fd(struct pri *pri);
extern int pri_fd(struct pri *pri);
#define PRI_PROGRESS
/* Send call proceeding */
int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
extern int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
#define PRI_PROCEEDING_FULL
/* Send call proceeding */
int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
/* Enable inband progress when a RELEASE is received */
void pri_set_inbandrelease(struct pri *pri, unsigned int enable);
extern int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
/* Enslave a PRI to another, so they share the same call list
(and maybe some timers) */
void pri_enslave(struct pri *master, struct pri *slave);
extern void pri_enslave(struct pri *master, struct pri *slave);
#define PRI_GR303_SUPPORT
#define PRI_ENSLAVE_SUPPORT
@@ -640,20 +581,20 @@ void pri_enslave(struct pri *master, struct pri *slave);
#define PRI_ANI
/* Send notification */
int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
extern int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
/* Get/Set PRI Timers */
#define PRI_GETSET_TIMERS
int pri_set_timer(struct pri *pri, int timer, int value);
int pri_get_timer(struct pri *pri, int timer);
int pri_timer2idx(char *timer);
extern int pri_set_timer(struct pri *pri, int timer, int value);
extern int pri_get_timer(struct pri *pri, int timer);
extern int pri_timer2idx(char *timer);
#define PRI_MAX_TIMERS 32
#define PRI_TIMER_N200 0 /* Maximum numer of q921 retransmissions */
#define PRI_TIMER_N201 1 /* Maximum numer of octets in an information field */
#define PRI_TIMER_N202 2 /* Maximum numer of transmissions of the TEI identity request message */
#define PRI_TIMER_K 3 /* Maximum number of outstanding I-frames */
#define PRI_TIMER_K 3 /* Maximum number of outstanding I-frames */
#define PRI_TIMER_T200 4 /* time between SABME's */
#define PRI_TIMER_T201 5 /* minimum time between retransmissions of the TEI Identity check messages */
@@ -681,10 +622,4 @@ int pri_timer2idx(char *timer);
#define PRI_TIMER_T321 26
#define PRI_TIMER_T322 27
#define PRI_TIMER_TM20 28 /* maximum time avaiting XID response */
#define PRI_TIMER_NM20 29 /* number of XID retransmits */
/* Get PRI version */
const char *pri_get_version(void);
#endif

2
mkdep
View File

@@ -1,4 +1,4 @@
#!/bin/sh -
#!/bin/bash -
#
# $OpenBSD: mkdep.gcc.sh,v 1.8 1998/09/02 06:40:07 deraadt Exp $
# $NetBSD: mkdep.gcc.sh,v 1.9 1994/12/23 07:34:59 jtc Exp $

189
pri.c
View File

@@ -81,7 +81,7 @@ char *pri_switch2str(int sw)
static void pri_default_timers(struct pri *pri, int switchtype)
{
static const int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
int x;
for (x = 0; x<PRI_MAX_TIMERS; x++) {
@@ -187,86 +187,73 @@ static int __pri_write(struct pri *pri, void *buf, int buflen)
return res;
}
/* Pass in the master for this function */
void __pri_free_tei(struct pri * p)
{
free (p);
}
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata)
{
struct pri *p;
if (!(p = calloc(1, sizeof(*p))))
return NULL;
p->bri = bri;
p->fd = fd;
p->read_func = rd;
p->write_func = wr;
p->userdata = userdata;
p->localtype = node;
p->switchtype = switchtype;
p->cref = 1;
p->sapi = (tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL;
p->tei = tei;
p->nsf = PRI_NSF_NONE;
p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
p->master = master;
p->callpool = &p->localpool;
pri_default_timers(p, switchtype);
if (master) {
pri_set_debug(p, master->debug);
if (master->sendfacility)
pri_facility_enable(p);
}
p = malloc(sizeof(struct pri));
if (p) {
memset(p, 0, sizeof(struct pri));
p->fd = fd;
p->read_func = rd;
p->write_func = wr;
p->userdata = userdata;
p->localtype = node;
p->switchtype = switchtype;
p->cref = 1;
p->sapi = Q921_SAPI_CALL_CTRL;
p->tei = 0;
p->nsf = PRI_NSF_NONE;
p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
p->master = master;
p->callpool = &p->localpool;
pri_default_timers(p, switchtype);
#ifdef LIBPRI_COUNTERS
p->q921_rxcount = 0;
p->q921_txcount = 0;
p->q931_rxcount = 0;
p->q931_txcount = 0;
p->q921_rxcount = 0;
p->q921_txcount = 0;
p->q931_rxcount = 0;
p->q931_txcount = 0;
#endif
if (switchtype == PRI_SWITCH_GR303_EOC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_OPS;
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0);
if (!p->subchannel) {
free(p);
p = NULL;
if (switchtype == PRI_SWITCH_GR303_EOC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_OPS;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
p->tei = Q921_TEI_GR303_TMC_CALLPROC;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
p->tei = Q921_TEI_GR303_TMC_SWITCHING;
} else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_PATH;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
p->tei = Q921_TEI_GR303_TMC_CALLPROC;
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0);
if (!p->subchannel) {
free(p);
p = NULL;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
p->tei = Q921_TEI_GR303_TMC_SWITCHING;
} else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_PATH;
/* Start Q.921 layer, Wait if we're the network */
if (p)
q921_start(p, p->localtype == PRI_CPE);
}
/* Start Q.921 layer, Wait if we're the network */
if (p)
q921_start(p, p->localtype == PRI_CPE);
return p;
}
void pri_call_set_useruser(q931_call *c, const char *userchars)
void pri_call_set_useruser(q931_call *c, char *userchars)
{
if (userchars)
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
}
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars)
void pri_sr_set_useruser(struct pri_sr *sr, char *userchars)
{
sr->useruserinfo = userchars;
}
@@ -283,15 +270,7 @@ int pri_restart(struct pri *pri)
struct pri *pri_new(int fd, int nodetype, int switchtype)
{
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
}
struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype)
{
if (ptpmode)
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
else
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL);
}
struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
@@ -300,7 +279,7 @@ struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read,
io_read = __pri_read;
if (!io_write)
io_write = __pri_write;
return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0);
return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata);
}
void *pri_get_userdata(struct pri *pri)
@@ -492,14 +471,6 @@ int pri_information(struct pri *pri, q931_call *call, char digit)
return q931_information(pri, call, digit);
}
int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits)
{
if (!pri || !call || !digits || !digits[0])
return -1;
return q931_keypad_facility(pri, call, digits);
}
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
@@ -550,44 +521,24 @@ int pri_channel_bridge(q931_call *call1, q931_call *call2)
if (!call1 || !call2)
return -1;
/* Make sure we have compatible switchtypes */
if (call1->pri->switchtype != call2->pri->switchtype)
/* Check switchtype compatibility */
if (call1->pri->switchtype != PRI_SWITCH_LUCENT5E ||
call2->pri->switchtype != PRI_SWITCH_LUCENT5E)
return -1;
/* Check for bearer capability */
if (call1->transcapability != call2->transcapability)
return -1;
/* Check to see if we're on the same PRI */
/* Check to see if calls are on the same PRI dchannel
* Currently only support calls on the same dchannel
*/
if (call1->pri != call2->pri)
return -1;
switch (call1->pri->switchtype) {
case PRI_SWITCH_NI2:
case PRI_SWITCH_LUCENT5E:
case PRI_SWITCH_ATT4ESS:
if (eect_initiate_transfer(call1->pri, call1, call2))
return -1;
else
return 0;
break;
case PRI_SWITCH_DMS100:
if (rlt_initiate_transfer(call1->pri, call1, call2))
return -1;
else
return 0;
break;
case PRI_SWITCH_QSIG:
call1->bridged_call = call2;
call2->bridged_call = call1;
if (anfpr_initiate_transfer(call1->pri, call1, call2))
return -1;
else
return 0;
break;
default:
return -1;
}
if (eect_initiate_transfer(call1->pri, call1, call2))
return -1;
return 0;
}
int pri_hangup(struct pri *pri, q931_call *call, int cause)
@@ -782,11 +733,6 @@ void pri_set_overlapdial(struct pri *pri,int state)
pri->overlapdial = state;
}
void pri_set_inbandrelease(struct pri *pri, unsigned int enable)
{
pri->acceptinbandrelease = (enable != 0);
}
int pri_fd(struct pri *pri)
{
return pri->fd;
@@ -829,7 +775,6 @@ char *pri_dump_info_str(struct pri *pri)
len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]);
len += sprintf(buf + len, "T305 Timer: %d\n", pri->timers[PRI_TIMER_T305]);
len += sprintf(buf + len, "T308 Timer: %d\n", pri->timers[PRI_TIMER_T308]);
len += sprintf(buf + len, "T309 Timer: %d\n", pri->timers[PRI_TIMER_T309]);
len += sprintf(buf + len, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]);
len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]);
@@ -855,7 +800,7 @@ void pri_enslave(struct pri *master, struct pri *slave)
struct pri_sr *pri_sr_new(void)
{
struct pri_sr *req;
req = malloc(sizeof(*req));
req = malloc(sizeof(struct pri_sr));
if (req)
pri_sr_init(req);
return req;

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,6 @@
#ifndef _PRI_FACILITY_H
#define _PRI_FACILITY_H
#include "pri_q931.h"
/* Protocol Profile field */
#define Q932_PROTOCOL_ROSE 0x11 /* X.219 & X.229 */
@@ -33,15 +32,6 @@
#define COMP_TYPE_NFE 0xAA
/* Operation ID values */
/* Q.952.7 (ECMA-178) ROSE operations (Transfer) */
#define ROSE_CALL_TRANSFER_IDENTIFY 7
#define ROSE_CALL_TRANSFER_ABANDON 8
#define ROSE_CALL_TRANSFER_INITIATE 9
#define ROSE_CALL_TRANSFER_SETUP 10
#define ROSE_CALL_TRANSFER_ACTIVE 11
#define ROSE_CALL_TRANSFER_COMPLETE 12
#define ROSE_CALL_TRANSFER_UPDATE 13
#define ROSE_SUBADDRESS_TRANSFER 14
/* Q.952 ROSE operations (Diverting) */
#define ROSE_DIVERTING_LEG_INFORMATION1 18
#define ROSE_DIVERTING_LEG_INFORMATION2 0x15
@@ -58,7 +48,6 @@
#define ROSE_AOC_IDENTIFICATION_OF_CHARGE 37
/* Q.SIG operations */
#define SS_CNID_CALLINGNAME 0
#define SS_ANFPR_PATHREPLACEMENT 4
#define SS_DIVERTING_LEG_INFORMATION2 21
#define SS_MWI_ACTIVATE 80
#define SS_MWI_DEACTIVATE 81
@@ -115,7 +104,7 @@
#define ASN1_CLAN_MASK 0xc0
#define ASN1_UNIVERSAL 0x00
#define ASN1_APPLICATION 0x40
#define ASN1_CONTEXT_SPECIFIC 0x80
#define ASN1_CONTEXT_SPECIFIC 0x80
#define ASN1_PRIVATE 0xc0
/* ASN.1 Length masks */
@@ -146,44 +135,30 @@
#define Q932_TON_SUBSCRIBER 0x04
#define Q932_TON_ABBREVIATED 0x06
/* RLT related Operations */
#define RLT_SERVICE_ID 0x3e
#define RLT_OPERATION_IND 0x01
#define RLT_THIRD_PARTY 0x02
struct rose_component {
u_int8_t type;
u_int8_t len;
u_int8_t data[0];
};
#if 1
#define GET_COMPONENT(component, idx, ptr, length) \
if ((idx)+2 > (length)) \
break; \
(component) = (struct rose_component*)&((ptr)[idx]); \
if ((idx)+(component)->len+2 > (length)) { \
if ((component)->len != ASN1_LEN_INDEF) \
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
}
#else /* Debugging */
#define GET_COMPONENT(component, idx, ptr, length) \
#define GET_COMPONENT(component, idx, ptr, length) \
if ((idx)+2 > (length)) \
break; \
(component) = (struct rose_component*)&((ptr)[idx]); \
if ((idx)+(component)->len+2 > (length)) { \
if ((component)->len != 128) \
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
} \
pri_message(pri, "XX %s:%d Got component %d (0x%02X), length %d\n", __FUNCTION__, __LINE__, (component)->type, (component)->type, (component)->len); \
}
/*
pri_message("XX Got component %d (0x%02X), length %d\n", (component)->type, (component)->type, (component)->len); \
if ((component)->len > 0) { \
int zzz; \
pri_message(pri, "XX Data:"); \
pri_message("XX Data:"); \
for (zzz = 0; zzz < (component)->len; ++zzz) \
pri_message(pri, " %02X", (component)->data[zzz]); \
pri_message(pri, "\n"); \
pri_message(" %02X", (component)->data[zzz]); \
pri_message("\n"); \
}
#endif
*/
#define NEXT_COMPONENT(component, idx) \
(idx) += (component)->len + 2
@@ -194,7 +169,6 @@ struct rose_component {
#define CHECK_COMPONENT(component, comptype, message) \
if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
pri_message(pri, (message), (component)->type); \
asn1_dump(pri, (component), (component)->len+2); \
break; \
}
@@ -255,51 +229,35 @@ struct rose_component {
(stack)[(stackpointer)]->len = (unsigned char *)&((data)[(idx)]) - (unsigned char *)(stack)[(stackpointer)] - 2; \
} while (0)
/* Decoder for the invoke ROSE component */
int rose_invoke_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
/* Decoder for the invoke part of a ROSE request */
extern int rose_invoke_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
/* Decoder for the return result ROSE component */
int rose_return_result_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
extern int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
/* Decoder for the return error ROSE component */
int rose_return_error_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
/* Decoder for the reject ROSE component */
int rose_reject_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len);
extern int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len);
/* Get Name types from ASN.1 */
int asn1_name_decode(void * data, int len, char *namebuf, int buflen);
extern int asn1_name_decode(void * data, int len, char *namebuf, int buflen);
int typeofnumber_from_q931(struct pri *pri, int ton);
extern int typeofnumber_from_q931(struct pri *pri, int ton);
int redirectingreason_from_q931(struct pri *pri, int redirectingreason);
extern int redirectingreason_from_q931(struct pri *pri, int redirectingreason);
/* Queues an MWI apdu on a the given call */
int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
extern int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
/* starts a 2BCT */
int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
extern int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
/* starts a QSIG Path Replacement */
extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
/* Use this function to queue a facility-IE born APDU onto a call
/* Use this function to queue a facility-IE born ADPU onto a call
* call is the call to use, messagetype is any one of the Q931 messages,
* apdu is the apdu data, apdu_len is the length of the apdu data */
int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data);
extern int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data);
/* Used by q931.c to cleanup the apdu queue upon destruction of a call */
int pri_call_apdu_queue_cleanup(q931_call *call);
extern int pri_call_apdu_queue_cleanup(q931_call *call);
/* Adds the "standard" APDUs to a call */
int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
int asn1_dump(struct pri *pri, void *comp, int len);
/* Adds the "standard" ADPUs to a call */
extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
#endif /* _PRI_FACILITY_H */

View File

@@ -25,12 +25,8 @@
#ifndef _PRI_INTERNAL_H
#define _PRI_INTERNAL_H
#include <stddef.h>
#include <sys/time.h>
#define DBGHEAD __FILE__ ":%d %s: "
#define DBGINFO __LINE__,__PRETTY_FUNCTION__
struct pri_sched {
struct timeval when;
void (*callback)(void *data);
@@ -64,8 +60,6 @@ struct pri {
int sapi;
int tei;
int protodisc;
unsigned int bri:1;
unsigned int acceptinbandrelease:1; /* Should we allow inband progress after RELEASE? */
/* Q.921 State */
int q921_state;
@@ -85,11 +79,7 @@ struct pri {
/* Various timers */
int sabme_timer; /* SABME retransmit */
int sabme_count; /* SABME retransmit counter for BRI */
int t203_timer; /* Max idle time */
int t202_timer;
int n202_counter;
int ri;
int t200_timer; /* T-200 retransmission timer */
/* All ISDN Timer values */
int timers[MAX_TIMERS];
@@ -139,8 +129,7 @@ struct pri_sr {
int redirectingpres;
int redirectingreason;
int justsignalling;
const char *useruserinfo;
int transferable;
char *useruserinfo;
};
/* Internal switch types */
@@ -217,7 +206,7 @@ struct q931_call {
char callernum[256];
char callername[256];
char keypad_digits[64]; /* Buffer for digits that come in KEYPAD_FACILITY */
char digitbuf[64]; /* Buffer for digits that come in KEYPAD_FACILITY */
int ani2; /* ANI II */
@@ -250,12 +239,6 @@ struct q931_call {
long aoc_units; /* Advice of Charge Units */
struct apdu_event *apdus; /* APDU queue for call */
int transferable;
unsigned int rlt_call_id; /* RLT call id */
/* Bridged call info */
q931_call *bridged_call; /* Pointer to other leg of bridged call */
};
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
@@ -272,8 +255,4 @@ extern void pri_error(struct pri *pri, char *fmt, ...);
void libpri_copy_string(char *dst, const char *src, size_t size);
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri);
void __pri_free_tei(struct pri *p);
#endif

View File

@@ -46,11 +46,10 @@
#define Q921_FRAMETYPE_I 0x0
#define Q921_FRAMETYPE_S 0x1
#define Q921_TEI_GROUP 127
#define Q921_TEI_PRI 0
#define Q921_TEI_GROUP 127
#define Q921_TEI_GR303_EOC_PATH 0
#define Q921_TEI_GR303_EOC_OPS 4
#define Q921_TEI_GR303_TMC_SWITCHING 0
#define Q921_TEI_GR303_TMC_SWITCHING 0
#define Q921_TEI_GR303_TMC_CALLPROC 0
#define Q921_SAPI_CALL_CTRL 0
@@ -64,14 +63,6 @@
#define Q921_SAPI_LAYER2_MANAGEMENT 63
#define Q921_TEI_IDENTITY_REQUEST 1
#define Q921_TEI_IDENTITY_ASSIGNED 2
#define Q921_TEI_IDENTITY_DENIED 3
#define Q921_TEI_IDENTITY_CHECK_REQUEST 4
#define Q921_TEI_IDENTITY_CHECK_RESPONSE 5
#define Q921_TEI_IDENTITY_REMOVE 6
#define Q921_TEI_IDENTITY_VERIFY 7
typedef struct q921_header {
#if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t sapi:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
@@ -163,12 +154,6 @@ typedef struct q921_frame {
#define Q921_INC(j) (j) = (((j) + 1) % 128)
typedef enum q921_state {
Q921_DOWN = 0,
Q921_TEI_UNASSIGNED,
Q921_TEI_AWAITING_ESTABLISH,
Q921_TEI_AWAITING_ASSIGN,
Q921_TEI_ASSIGNED,
Q921_NEGOTIATION,
Q921_LINK_CONNECTION_RELEASED, /* Also known as TEI_ASSIGNED */
Q921_LINK_CONNECTION_ESTABLISHED,
Q921_AWAITING_ESTABLISH,

View File

@@ -243,10 +243,6 @@ typedef struct q931_ie {
/* EuroISDN */
#define Q931_SENDING_COMPLETE 0xa1
/* Q.SIG specific */
#define QSIG_IE_TRANSIT_COUNT 0x31
extern int q931_receive(struct pri *pri, q931_h *h, int len);
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
@@ -261,8 +257,6 @@ extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int non
extern int q931_information(struct pri *pri, q931_call *call, char digit);
extern int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits);
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
extern int q931_release(struct pri *pri, q931_call *call, int cause);
@@ -285,7 +279,5 @@ extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
extern void __q931_destroycall(struct pri *pri, q931_call *c);
extern void q931_dl_indication(struct pri *pri, int event);
#endif

View File

@@ -26,37 +26,34 @@
#define _PRI_TIMERS_H
/* -1 means we dont currently support the timer/counter */
#define PRI_TIMERS_DEFAULT { \
3, /* N200 */ \
-1, /* N201 */ \
3, /* N202 */ \
7, /* K */ \
#define PRI_TIMERS_DEFAULT { 3, /* N200 */ \
-1, /* N201 */ \
-1, /* N202 */ \
7, /* K */ \
1000, /* T200 */ \
-1, /* T201 */ \
10000, /* T202 */ \
-1, /* T201 */ \
-1, /* T202 */ \
10000, /* T203 */ \
-1, /* T300 */ \
-1, /* T301 */ \
-1, /* T302 */ \
-1, /* T303 */ \
-1, /* T304 */ \
-1, /* T300 */ \
-1, /* T301 */ \
-1, /* T302 */ \
-1, /* T303 */ \
-1, /* T304 */ \
30000, /* T305 */ \
-1, /* T306 */ \
-1, /* T307 */ \
-1, /* T306 */ \
-1, /* T307 */ \
4000, /* T308 */ \
-1, /* T309 */ \
-1, /* T310 */ \
-1, /* T309 */ \
-1, /* T310 */ \
4000, /* T313 */ \
-1, /* T314 */ \
-1, /* T316 */ \
-1, /* T317 */ \
-1, /* T318 */ \
-1, /* T319 */ \
-1, /* T320 */ \
-1, /* T321 */ \
-1, /* T322 */ \
2500, /* TM20 - Q.921 Appendix IV */ \
3, /* NM20 - Q.921 Appendix IV */ \
-1, /* T314 */ \
-1, /* T316 */ \
-1, /* T317 */ \
-1, /* T318 */ \
-1, /* T319 */ \
-1, /* T320 */ \
-1, /* T321 */ \
-1 /* T322 */ \
}
/* XXX Only our default timers are setup now XXX */

View File

@@ -37,7 +37,11 @@
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <zaptel/zaptel.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"

View File

@@ -35,9 +35,6 @@ int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), vo
{
int x;
struct timeval tv;
/* Scheduling runs on master channels only */
while (pri->master)
pri = pri->master;
for (x=1;x<MAX_SCHED;x++)
if (!pri->pri_sched[x].callback)
break;
@@ -116,8 +113,6 @@ pri_event *pri_schedule_run(struct pri *pri)
void pri_schedule_del(struct pri *pri,int id)
{
while (pri->master)
pri = pri->master;
if ((id >= MAX_SCHED) || (id < 0))
pri_error(pri, "Asked to delete sched id %d???\n", id);
pri->pri_sched[id].callback = NULL;

View File

@@ -40,7 +40,11 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <zaptel/zaptel.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include "libpri.h"
@@ -294,7 +298,7 @@ static int run_pri(int dfd, int swtype, int node)
fd_set rfds, efds;
int res,x;
pri = pri_new_bri(dfd, 1, node, swtype);
pri = pri_new(dfd, node, swtype);
if (!pri) {
fprintf(stderr, "Unable to create PRI\n");
return -1;

472
q921.c
View File

@@ -51,8 +51,6 @@
} while(0)
static void reschedule_t203(struct pri *pri);
static void q921_restart(struct pri *pri, int now);
static void q921_tei_release_and_reacquire(struct pri *master);
static void q921_discard_retransmissions(struct pri *pri)
{
@@ -70,10 +68,8 @@ static void q921_discard_retransmissions(struct pri *pri)
static int q921_transmit(struct pri *pri, q921_h *h, int len)
{
int res;
if (pri->master)
pri = pri->master;
return q921_transmit(pri->master, h, len);
#ifdef RANDOM_DROPS
if (!(random() % 3)) {
pri_message(pri, " === Dropping Packet ===\n");
@@ -84,7 +80,7 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
pri->q921_txcount++;
#endif
/* Just send it raw */
if (pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
/* Write an extra two bytes for the FCS */
res = pri->write_func ? pri->write_func(pri, h, len + 2) : 0;
@@ -96,49 +92,6 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
return 0;
}
static void q921_send_tei(struct pri *pri, int message, int ri, int ai, int iscommand)
{
q921_u *f;
if (!(f = calloc(1, sizeof(*f) + 5)))
return;
Q921_INIT(pri, *f);
f->h.c_r = (pri->localtype == PRI_NETWORK) ? iscommand : !iscommand;
f->ft = Q921_FRAMETYPE_U;
f->data[0] = 0x0f; /* Management entity */
f->data[1] = (ri >> 8) & 0xff;
f->data[2] = ri & 0xff;
f->data[3] = message;
f->data[4] = (ai << 1) | 1;
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Sending TEI management message %d, TEI=%d\n", message, ai);
q921_transmit(pri, (q921_h *)f, 8);
free(f);
}
static void q921_tei_request(void *vpri)
{
struct pri *pri = (struct pri *)vpri;
if (pri->subchannel) {
pri_error(pri, "Cannot request TEI while its already assigned\n");
return;
}
pri->n202_counter++;
#if 0
if (pri->n202_counter > pri->timers[PRI_TIMER_N202]) {
pri_error(pri, "Unable to assign TEI from network\n");
return;
}
#endif
pri->ri = random() % 65535;
q921_send_tei(pri, Q921_TEI_IDENTITY_REQUEST, pri->ri, Q921_TEI_GROUP, 1);
if (pri->t202_timer)
pri_schedule_del(pri, pri->t202_timer);
pri->t202_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T202], q921_tei_request, pri);
}
static void q921_send_ua(struct pri *pri, int pfbit)
{
q921_h h;
@@ -158,7 +111,7 @@ static void q921_send_ua(struct pri *pri, int pfbit)
pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
return;
}
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Sending Unnumbered Acknowledgement\n");
q921_transmit(pri, &h, 3);
}
@@ -190,20 +143,9 @@ static void q921_send_sabme(void *vpri, int now)
pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
return;
}
if (pri->bri && (pri->state == Q921_AWAITING_ESTABLISH)) {
if (pri->sabme_count >= pri->timers[PRI_TIMER_N200]) {
pri_schedule_del(pri, pri->sabme_timer);
pri->sabme_timer = 0;
q921_tei_release_and_reacquire(pri->master);
} else {
pri->sabme_count++;
}
}
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Sending Set Asynchronous Balanced Mode Extended\n");
q921_transmit(pri, &h, 3);
if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_AWAITING_ESTABLISH)
pri_message(pri, DBGHEAD "q921_state now is Q921_AWAITING_ESTABLISH\n", DBGINFO);
pri->q921_state = Q921_AWAITING_ESTABLISH;
}
@@ -224,7 +166,7 @@ static int q921_ack_packet(struct pri *pri, int num)
prev->next = f->next;
else
pri->txqueue = f->next;
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue ? pri->txqueue->h.n_s : -1);
/* Update v_a */
pri->v_a = num;
@@ -238,7 +180,7 @@ static int q921_ack_packet(struct pri *pri, int num)
while(f) {
if (!f->transmitted) {
/* Send it now... */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Finally transmitting %d, since window opened up\n", f->h.n_s);
f->transmitted++;
pri->windowlen++;
@@ -264,7 +206,7 @@ static void reschedule_t203(struct pri *pri)
{
if (pri->t203_timer) {
pri_schedule_del(pri, pri->t203_timer);
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Restarting T203 counter\n");
/* Nothing to transmit, start the T203 counter instead */
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
@@ -287,31 +229,31 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
return ev;
}
/* Cancel each packet as necessary */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- ACKing all packets from %d to (but not including) %d\n", pri->v_a, ack);
for (x=pri->v_a; x != ack; Q921_INC(x))
cnt += q921_ack_packet(pri, x);
if (!pri->txqueue) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Since there was nothing left, stopping T200 counter\n");
/* Something was ACK'd. Stop T200 counter */
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
if (pri->t203_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Stopping T203 counter since we got an ACK\n");
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = 0;
}
if (pri->txqueue) {
/* Something left to transmit, Start the T200 counter again if we stopped it */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue->h.n_s);
if (!pri->t200_timer)
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Nothing left, starting T203 counter\n");
/* Nothing to transmit, start the T203 counter instead */
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
@@ -339,7 +281,7 @@ static void q921_reject(struct pri *pri, int pf)
pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
return;
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Sending Reject (%d)\n", pri->v_r);
pri->sentrej = 1;
q921_transmit(pri, &h, 4);
@@ -371,7 +313,7 @@ static void q921_rr(struct pri *pri, int pbit, int cmd) {
return;
}
pri->v_na = pri->v_r; /* Make a note that we've already acked this */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r);
q921_transmit(pri, &h, 4);
}
@@ -379,10 +321,9 @@ static void q921_rr(struct pri *pri, int pbit, int cmd) {
static void t200_expire(void *vpri)
{
struct pri *pri = vpri;
if (pri->txqueue) {
/* Retransmit first packet in the queue, setting the poll bit */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- T200 counter expired, What to do...\n");
/* Force Poll bit */
pri->txqueue->h.p_f = 1;
@@ -391,55 +332,46 @@ static void t200_expire(void *vpri)
pri->v_na = pri->v_r;
pri->solicitfbit = 1;
pri->retrans++;
/* Up to three retransmissions */
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
/* Reschedule t200_timer */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
if (pri->busy)
q921_rr(pri, 1, 1);
else {
if (!pri->txqueue->transmitted)
pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Timeout occured, restarting PRI\n");
if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n",DBGINFO);
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
/* Up to three retransmissions */
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
/* Reschedule t200_timer */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
if (pri->busy)
q921_rr(pri, 1, 1);
else {
if (!pri->txqueue->transmitted)
pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
}
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Timeout occured, restarting PRI\n");
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
}
} else if (pri->solicitfbit) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Retrying poll with f-bit\n");
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Retrying poll with f-bit\n");
pri->retrans++;
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
pri->solicitfbit = 1;
q921_rr(pri, 1, 1);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Timeout occured, restarting PRI\n");
if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
if (pri->bri && pri->master) {
q921_tei_release_and_reacquire(pri->master);
return;
} else {
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
}
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
}
} else {
pri_error(pri, "T200 counter expired, nothing to send...\n");
@@ -450,10 +382,10 @@ static void t200_expire(void *vpri)
int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
{
q921_frame *f, *prev=NULL;
for (f=pri->txqueue; f; f = f->next) prev = f;
f = calloc(1, sizeof(q921_frame) + len + 2);
f = malloc(sizeof(q921_frame) + len + 2);
if (f) {
memset(f,0,sizeof(q921_frame) + len + 2);
Q921_INIT(pri, f->h);
switch(pri->localtype) {
case PRI_NETWORK:
@@ -491,23 +423,23 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
q921_transmit(pri, (q921_h *)(&f->h), f->len);
f->transmitted++;
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n",
f->h.n_s, pri->windowlen, pri->window);
}
}
if (pri->t203_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Stopping T_203 timer\n");
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = 0;
}
if (!pri->t200_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Starting T_200 timer\n");
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
} else {
@@ -521,7 +453,7 @@ static void t203_expire(void *vpri)
{
struct pri *pri = vpri;
if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "T203 counter expired, sending RR and scheduling T203 again\n");
/* Solicit an F-bit in the other's RR */
pri->solicitfbit = 1;
@@ -530,7 +462,7 @@ static void t203_expire(void *vpri)
/* Start timer T200 to resend our RR if we don't get it */
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
pri->t203_timer = 0;
}
@@ -715,25 +647,18 @@ static pri_event *q921_dchannel_up(struct pri *pri)
q921_reset(pri);
/* Stop any SABME retransmissions */
if (pri->sabme_timer) {
pri_schedule_del(pri, pri->sabme_timer);
pri->sabme_timer = 0;
}
pri_schedule_del(pri, pri->sabme_timer);
pri->sabme_timer = 0;
/* Reset any rejects */
pri->sentrej = 0;
/* Go into connection established state */
if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED)
pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_ESTABLISHED\n", DBGINFO);
pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;
/* Start the T203 timer */
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
/* Notify Layer 3 */
q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
/* Report event that D-Channel is now up */
pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
return &pri->ev;
@@ -744,9 +669,6 @@ static pri_event *q921_dchannel_down(struct pri *pri)
/* Reset counters, reset sabme timer etc */
q921_reset(pri);
/* Notify Layer 3 */
q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
/* Report event that D-Channel is now up */
pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
return &pri->ev;
@@ -761,20 +683,14 @@ void q921_reset(struct pri *pri)
pri->v_na = 0;
pri->window = pri->timers[PRI_TIMER_K];
pri->windowlen = 0;
if (pri->sabme_timer)
pri_schedule_del(pri, pri->sabme_timer);
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
if (pri->t200_timer)
pri_schedule_del(pri, pri->t200_timer);
pri_schedule_del(pri, pri->sabme_timer);
pri_schedule_del(pri, pri->t203_timer);
pri_schedule_del(pri, pri->t200_timer);
pri->sabme_timer = 0;
pri->sabme_count = 0;
pri->t203_timer = 0;
pri->t200_timer = 0;
pri->busy = 0;
pri->solicitfbit = 0;
if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->retrans = 0;
pri->sentrej = 0;
@@ -783,101 +699,6 @@ void q921_reset(struct pri *pri)
q921_discard_retransmissions(pri);
}
static void q921_tei_release_and_reacquire(struct pri *master)
{
/* Make sure the master is passed into this function */
q921_dchannel_down(master->subchannel);
__pri_free_tei(master->subchannel);
master->subchannel = NULL;
master->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
master->schedev = 1;
q921_start(master, master->localtype == PRI_CPE);
}
static pri_event *q921_receive_MDL(struct pri *pri, q921_u *h, int len)
{
int ri;
struct pri *sub;
int tei;
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "Received MDL message\n");
if (h->data[0] != 0x0f) {
pri_error(pri, "Received MDL with unsupported management entity %02x\n", h->data[0]);
return NULL;
}
if (!(h->data[4] & 0x01)) {
pri_error(pri, "Received MDL with multibyte TEI identifier\n");
return NULL;
}
ri = (h->data[1] << 8) | h->data[2];
tei = (h->data[4] >> 1);
switch(h->data[3]) {
case Q921_TEI_IDENTITY_REQUEST:
if (tei != 127) {
pri_error(pri, "Received TEI identity request with invalid TEI %d\n", tei);
q921_send_tei(pri, Q921_TEI_IDENTITY_DENIED, ri, tei, 1);
}
/* Go to master */
for (sub = pri; sub->master; sub = sub->master);
tei = 64;
while(sub->subchannel) {
if(sub->subchannel->tei == tei)
++tei;
}
sub->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1);
if (!sub->subchannel) {
pri_error(pri, "Unable to allocate D-channel for new TEI %d\n", tei);
return NULL;
}
q921_send_tei(pri, Q921_TEI_IDENTITY_ASSIGNED, ri, tei, 1);
break;
case Q921_TEI_IDENTITY_ASSIGNED:
if (ri != pri->ri) {
pri_message(pri, "TEI assignment received for invalid Ri %02x (our is %02x)\n", ri, pri->ri);
return NULL;
}
if (pri->t202_timer) {
pri_schedule_del(pri, pri->t202_timer);
pri->t202_timer = 0;
}
if (pri->subchannel && (pri->subchannel->tei == tei)) {
pri_error(pri, "TEI already assigned (new is %d, current is %d)\n", tei, pri->subchannel->tei);
q921_tei_release_and_reacquire(pri);
return NULL;
}
pri_message(pri, "TEI assiged to %d\n", tei);
pri->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1);
if (!pri->subchannel) {
pri_error(pri, "Unable to allocate D-channel for new TEI %d\n", tei);
return NULL;
}
pri->q921_state = Q921_TEI_ASSIGNED;
break;
case Q921_TEI_IDENTITY_CHECK_REQUEST:
/* We're assuming one TEI per PRI in TE PTMP mode */
/* If no subchannel (TEI) ignore */
if (!pri->subchannel)
return NULL;
/* If it's addressed to the group TEI or to our TEI specifically, we respond */
if ((tei == Q921_TEI_GROUP) || (tei == pri->subchannel->tei))
q921_send_tei(pri, Q921_TEI_IDENTITY_CHECK_RESPONSE, random() % 65535, pri->subchannel->tei, 1);
break;
case Q921_TEI_IDENTITY_REMOVE:
/* XXX: Assuming multiframe mode has been disconnected already */
if (!pri->subchannel)
return NULL;
if ((tei == Q921_TEI_GROUP) || (tei == pri->subchannel->tei)) {
q921_tei_release_and_reacquire(pri);
}
}
return NULL; /* Do we need to return something??? */
}
static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
{
q921_frame *f;
@@ -918,69 +739,69 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
if (h->s.p_f) {
/* If it's a p/f one then send back a RR in return with the p/f bit set */
if (pri->solicitfbit) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got RR response to our frame\n");
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
q921_rr(pri, 1, 0);
}
pri->solicitfbit = 0;
}
break;
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got receiver not ready\n");
if(h->s.p_f) {
/* Send RR if poll bit set */
q921_rr(pri, h->s.p_f, 0);
}
pri->busy = 1;
break;
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got reject requesting packet %d... Retransmitting.\n", h->s.n_r);
if (h->s.p_f) {
/* If it has the poll bit set, send an appropriate supervisory response */
q921_rr(pri, 1, 0);
}
sendnow = 0;
/* Resend the proper I-frame */
for(f=pri->txqueue;f;f=f->next) {
if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
/* Matches the request, or follows in our window, and has
already been transmitted. */
sendnow = 1;
pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
}
}
if (!sendnow) {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
}
} else {
/* Hrm, we have nothing to send, but have been REJ'd. Reset v_a, v_s, etc */
pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
pri->v_a = h->s.n_r;
pri->v_s = h->s.n_r;
/* Reset t200 timer if it was somehow going */
if (pri->t200_timer) {
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
/* Reset and restart t203 timer */
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
}
break;
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got receiver not ready\n");
if(h->s.p_f) {
/* Send RR if poll bit set */
q921_rr(pri, h->s.p_f, 0);
}
pri->busy = 1;
break;
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got reject requesting packet %d... Retransmitting.\n", h->s.n_r);
if (h->s.p_f) {
/* If it has the poll bit set, send an appropriate supervisory response */
q921_rr(pri, 1, 0);
}
sendnow = 0;
/* Resend the proper I-frame */
for(f=pri->txqueue;f;f=f->next) {
if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
/* Matches the request, or follows in our window, and has
already been transmitted. */
sendnow = 1;
pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
}
}
if (!sendnow) {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
}
} else {
/* Hrm, we have nothing to send, but have been REJ'd. Reset v_a, v_s, etc */
pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
pri->v_a = h->s.n_r;
pri->v_s = h->s.n_r;
/* Reset t200 timer if it was somehow going */
if (pri->t200_timer) {
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
/* Reset and restart t203 timer */
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
}
break;
default:
pri_error(pri, "!! XXX Unknown Supervisory frame ss=0x%02x,pf=%02xnr=%02x vs=%02x, va=%02x XXX\n", h->s.ss, h->s.p_f, h->s.n_r,
pri->v_s, pri->v_a);
@@ -997,49 +818,38 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
if (h->u.p_f) {
/* Section 5.7.1 says we should restart on receiving a DM response with the f-bit set to
one, but we wait T200 first */
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got DM Mode from peer.\n");
/* Disconnected mode, try again after T200 */
ev = q921_dchannel_down(pri);
q921_restart(pri, 0);
q921_start(pri, 0);
return ev;
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
#if 0
/* Requesting that we start */
q921_restart(pri, 0);
q921_start(pri, 0);
#endif
}
break;
} else if (!h->u.m2) {
if ((pri->sapi == Q921_SAPI_LAYER2_MANAGEMENT) && (pri->tei == Q921_TEI_GROUP))
q921_receive_MDL(pri, (q921_u *)h, len);
else {
int res;
res = q931_receive(pri, (q931_h *) h->u.data, len - 3);
if (res == -1) {
return NULL;
}
if (res & Q931_RES_HAVEEVENT)
return &pri->ev;
}
pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
}
break;
case 2:
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got Disconnect from peer.\n");
/* Acknowledge */
q921_send_ua(pri, h->u.p_f);
ev = q921_dchannel_down(pri);
q921_restart(pri, 0);
q921_start(pri, 0);
return ev;
case 3:
if (h->u.m2 == 3) {
/* SABME */
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) {
if (pri->debug & PRI_DEBUG_Q921_STATE) {
pri_message(pri, "-- Got SABME from %s peer.\n", h->h.c_r ? "network" : "cpe");
}
if (h->h.c_r) {
@@ -1061,21 +871,12 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
} else if (h->u.m2 == 0) {
/* It's a UA */
if (pri->q921_state == Q921_AWAITING_ESTABLISH) {
if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) {
if (pri->debug & PRI_DEBUG_Q921_STATE) {
pri_message(pri, "-- Got UA from %s peer Link up.\n", h->h.c_r ? "cpe" : "network");
}
return q921_dchannel_up(pri);
} else if ((pri->q921_state >= Q921_TEI_ASSIGNED) && pri->bri) {
/* Possible duplicate TEI assignment */
if (pri->master)
q921_tei_release_and_reacquire(pri->master);
else
pri_error(pri, "Huh!? no master found\n");
} else {
/* Since we're not in the AWAITING_ESTABLISH STATE, it's unsolicited */
} else
pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state);
}
} else
pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
break;
@@ -1100,31 +901,28 @@ static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
/* Discard FCS */
len -= 2;
if (!pri->master && pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
/* Check some reject conditions -- Start by rejecting improper ea's */
if (h->h.ea1 || !(h->h.ea2))
return NULL;
#if 0 /* Will be rejected by subchannel analyzis */
/* Check for broadcasts - not yet handled */
if (h->h.tei == Q921_TEI_GROUP)
return NULL;
#endif
if (!((h->h.sapi == pri->sapi) && ((h->h.tei == pri->tei) || (h->h.tei == Q921_TEI_GROUP)))) {
/* Check for SAPIs we don't yet handle */
/* Check for SAPIs we don't yet handle */
if ((h->h.sapi != pri->sapi) || (h->h.tei != pri->tei)) {
#ifdef PROCESS_SUBCHANNELS
/* If it's not us, try any subchannels we have */
if (pri->subchannel)
return q921_receive(pri->subchannel, h, len + 2);
else {
else
#endif
return NULL;
}
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "Handling message for SAPI/TEI=%d/%d\n", h->h.sapi, h->h.tei);
ev = __q921_receive_qualified(pri, h, len);
reschedule_t203(pri);
return ev;
@@ -1140,7 +938,7 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
return e;
}
static void q921_restart(struct pri *pri, int now)
void q921_start(struct pri *pri, int now)
{
if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
pri_error(pri, "!! q921_start: Not in 'Link Connection Released' state\n");
@@ -1151,15 +949,3 @@ static void q921_restart(struct pri *pri, int now)
/* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
q921_send_sabme(pri, now);
}
void q921_start(struct pri *pri, int isCPE)
{
q921_reset(pri);
if ((pri->sapi == Q921_SAPI_LAYER2_MANAGEMENT) && (pri->tei == Q921_TEI_GROUP)) {
pri->q921_state = Q921_DOWN;
if (isCPE)
q921_tei_request(pri);
} else {
q921_send_sabme(pri, isCPE);
}
}

870
q931.c

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,11 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <zaptel/zaptel.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__) || defined(SOLARIS)
#include <zaptel.h>
#endif
#ifndef SOLARIS
#include <zap.h>
#endif
@@ -64,7 +68,7 @@ static struct pri *first, *cur;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define TEST_CALLS 1
#define TEST_CALLS 32
static void event1(struct pri *pri, pri_event *e)
{
@@ -143,7 +147,7 @@ static void event2(struct pri *pri, pri_event *e)
}
}
static void testmsg(struct pri *pri, char *s)
static void testmsg(char *s)
{
char *c;
static int keeplast = 0;
@@ -169,7 +173,7 @@ static void testmsg(struct pri *pri, char *s)
keeplast = 0;
}
static void testerr(struct pri *pri, char *s)
static void testerr(char *s)
{
char *c;
static int keeplast = 0;
@@ -232,9 +236,9 @@ static void *dchan(void *data)
}
if (e) {
if (first == pri) {
event1(e->gen.pri, e);
event1(pri, e);
} else {
event2(e->gen.pri, e);
event2(pri, e);
}
}
pthread_mutex_unlock(&lock);
@@ -254,23 +258,21 @@ int main(int argc, char *argv[])
perror("socketpair");
exit(1);
}
if (!(pri = pri_new_bri(pair[0], 0, PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
if (!(pri = pri_new(pair[0], PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
perror("pri(0)");
exit(1);
}
first = pri;
pri_set_debug(pri, DEBUG_LEVEL);
pri_facility_enable(pri);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(0)");
exit(1);
}
if (!(pri = pri_new_bri(pair[1], 0, PRI_CPE, PRI_DEF_SWITCHTYPE))) {
if (!(pri = pri_new(pair[1], PRI_CPE, PRI_DEF_SWITCHTYPE))) {
perror("pri(1)");
exit(1);
}
pri_set_debug(pri, DEBUG_LEVEL);
pri_facility_enable(pri);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(1)");
exit(1);