Compare commits

...

206 Commits
0.3.1 ... 1.2.2

Author SHA1 Message Date
Russell Bryant
e523c168a2 importing ChangeLog for 1.2.2 release
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.2.2@295 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-01-18 04:49:50 +00:00
Russell Bryant
91ab439a15 Creating tag for the release of libpri-1.2.2
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.2.2@294 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2006-01-18 04:49:49 +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
Matthew Fredrickson
014fd45a37 Fix typo in commit
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@255 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-10-25 16:59:59 +00:00
Matthew Fredrickson
89384a8472 Add protection block
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@254 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-10-21 21:21:22 +00:00
Matthew Fredrickson
e0de929e20 Updates so that one can do user to user IE transmission
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@253 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-10-21 20:20:22 +00:00
Matthew Fredrickson
160b8c91b8 Fix so that APDUs are not added multiple times for a call (Bug #5361)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@252 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-10-04 17:35:48 +00:00
Kevin P. Fleming
326c5c66d6 allow Makefile to be used more easily in automated build environments (issue #5291)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@251 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-26 15:57:23 +00:00
Anthony Minessale II
9842934154 fixing compile errors! check the patch but if it's wrong it's better than not compiling at all
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@250 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-16 17:15:57 +00:00
Matthew Fredrickson
f64108e394 Don't specify DS1 on Q.SIG
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@249 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-16 17:02:44 +00:00
Matthew Fredrickson
83c78f9e85 Q.SIG fix. Don't send DISPLAY IE for callername
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@248 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-15 15:46:09 +00:00
Mark Spencer
cfee7ff007 Add ability to restart PRI at Q.921 layer
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@247 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-13 02:19:00 +00:00
Kevin P. Fleming
4bbe741b99 send calling plan info for RDNIS and originally called number in new call events
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@246 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-09-02 18:37:03 +00:00
Kevin P. Fleming
3269a4b034 cleanups and fixes for Solaris (issue #4999)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@245 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-08-29 19:12:31 +00:00
Matthew Fredrickson
21d693f0b4 Fix pridump so that it works again (bug 4803) Thanks PCadach
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@243 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-27 13:14:05 +00:00
Kevin P. Fleming
598e8092f1 make copy_string able to build on older compilers (bug #4714)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@242 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-15 16:29:20 +00:00
Matthew Fredrickson
bbd1d88f70 Fix for gcc-4.0
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@241 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-13 14:09:16 +00:00
Matthew Fredrickson
badbe8cf1f Fix for non constructed number component
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@240 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-12 20:15:20 +00:00
Kevin P. Fleming
25cb0b7457 forward more ANI information to users of libpri (bug #4571)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@239 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-12 02:33:25 +00:00
Matthew Fredrickson
ac9bba5121 Don't allow notification codes outside of the Q.931 spec for switches other
than EuroISDN.  Also take out some old facility IE code.


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@238 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-07-11 17:48:30 +00:00
Matthew Fredrickson
00d12810bb more cause stuff
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@235 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-29 21:28:23 +00:00
Matthew Fredrickson
d8ac58da6d Allow cause IEs to be passed through libpri in PROGRESS messages
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@234 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-29 17:27:03 +00:00
Kevin P. Fleming
3fe76c6aea correct improperly applied patch from bug 4405 (bug #4573)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@231 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-22 19:27:43 +00:00
Kevin P. Fleming
f622f51004 use libpri_copy_string() (same as ast_copy_string()) instead of strncpy
update file headers for proper copyrights and licenses
various other minor optimizations


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@230 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-21 22:47:39 +00:00
Kevin P. Fleming
6694b84e88 record network-provided-number as ANI when supplied (bug #4537)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@229 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-21 20:37:22 +00:00
Matthew Fredrickson
849ec03cb0 more ASN.1 parsing fixes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@228 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-03 18:29:25 +00:00
Matthew Fredrickson
9bcef26cd6 More ASN.1 size fixes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@227 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-02 22:40:35 +00:00
Matthew Fredrickson
c9710c8b33 More fixes for indefinite length in the ASN.1 parsing routines
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@226 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-02 20:58:32 +00:00
Matthew Fredrickson
3c1f055287 Have a couple of operations wrong for Q.SIG from the merge
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@225 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-06-02 15:55:49 +00:00
Russell Bryant
b81d7389a9 add missing argument (bug #4405)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@223 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-29 15:08:23 +00:00
Matthew Fredrickson
6e98b36cfb Explicit/Implicit ds1 selection changes for NFAS
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@222 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-24 15:03:33 +00:00
Matthew Fredrickson
6341ab3c6e Bug fixes in output debug code
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@221 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-23 18:15:06 +00:00
Matthew Fredrickson
2a263061f2 New pri_set_message api
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@220 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-23 16:51:30 +00:00
Matthew Fredrickson
64088fe864 PRI debug additions -- testing...
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@219 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-23 15:06:33 +00:00
Matthew Fredrickson
1e4b4fbdbb Explicit versus implicit DS1 selection options
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@218 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-19 14:06:43 +00:00
Matthew Fredrickson
8205ce358a Add support to enable/disable facility IE Supplementary Services
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@217 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-12 14:48:00 +00:00
Matthew Fredrickson
3803535593 pri show debug feature (bug 4210)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@215 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-05-10 21:02:41 +00:00
Kevin P. Fleming
099ee35431 suppress harmless warning (bug #4061)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@214 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-22 02:37:37 +00:00
Matthew Fredrickson
3e8f5869ae More little callername tweaks
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@213 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-21 21:58:21 +00:00
Matthew Fredrickson
4ecc27efab Round two with CPE callername sending
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@212 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-21 19:58:14 +00:00
Kevin P. Fleming
0a3a816622 ensure that Q.921/Q.931 structures are always aligned on 8-bit boundaries, even on platforms with non-default structure alignment (bug #4052)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@211 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-20 15:23:35 +00:00
Matthew Fredrickson
c03b48392a Q.SIG timer rearrangement
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@210 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-08 23:04:37 +00:00
Matthew Fredrickson
e4fbf8c388 BIG libpri-matt merge. Adding new event information and fixing the
parsing routing for DivertingLegInformation2 so that it can work with
indefinite length-encoded ASN.1 parameters


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@209 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-06 19:42:41 +00:00
Mark Spencer
7f866680ad Add ability to detect old libpri
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@208 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-06 19:14:39 +00:00
Matthew Fredrickson
fa826f1151 Add missing PRI/Q.931 progress mask
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@207 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-05 21:54:15 +00:00
Matthew Fredrickson
240cd3ece0 Merging Advice of Charge code into libpri (bug #3843)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@206 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-05 03:55:58 +00:00
Kevin P. Fleming
241f97782c silence signed/unsigned warnings with upcoming gcc-4 (bug #3915)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@204 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-04-03 23:07:55 +00:00
Matthew Fredrickson
02abf57233 Fix callernumber IE to be read only once
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@203 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-31 20:56:52 +00:00
Mark Spencer
23a638cf66 Allow PRI to support callback functions (Diana's patch, placed in public domain)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@202 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-17 15:46:23 +00:00
Matthew Fredrickson
d7b60b28e0 Just send callername APDUs if we're network side
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@201 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-16 15:10:41 +00:00
Matthew Fredrickson
84adda970c Fixed some free() bugs in the APDU code.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@200 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-10 20:37:16 +00:00
Matthew Fredrickson
545e628f65 Make sure WE release the connection if we're the one that started the signalling only connection
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@197 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-04 15:56:37 +00:00
Matthew Fredrickson
9d279a6d6e Adding debug level for APDUs
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@196 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-02 16:03:22 +00:00
Matthew Fredrickson
86cf50b9c3 Big PRI commit. Merges bugs 3623 and 3554 back. Includes additional
event for Q931_IE_KEYPAD_FACILITY and all of the various Q.SIG functions,
2BCT on 5ESS, and a few other random changes


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@195 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-03-02 15:56:11 +00:00
Mark Spencer
c164cccc87 Reflect 7k audio name change (bug #3547)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@194 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-02-28 06:34:24 +00:00
Mark Spencer
bbaa1ed2e7 Make exception for OpenH323 here, not just in Asterisk.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@190 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-02-19 22:04:11 +00:00
Mark Spencer
e7b075b6f6 Add missing line from bug #3448
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@188 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-02-05 16:54:52 +00:00
Matthew Fredrickson
6f32fe5793 Support for DivertingLegInformation2 ROSE ADPU. Thanks PCadach!
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@187 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-02-03 22:14:44 +00:00
Mark Spencer
75a5597f39 Fix mkdep for dynamic library version (bug #3497)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@186 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-02-03 05:09:05 +00:00
Mark Spencer
0e0d251e15 Present message code properly (bug #3447)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@185 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-28 22:11:24 +00:00
Mark Spencer
dc74d755a8 Check for data presense (bug #3435 again)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@184 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-27 20:47:10 +00:00
Mark Spencer
14796a30af Produce more verbose PRI output (bug #3435)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@183 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-27 06:05:09 +00:00
Mark Spencer
f89bbdd6a3 Fix generic digit byte order (bug #2788)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@182 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-27 05:39:17 +00:00
Matthew Fredrickson
1cfe36a944 Don't send callername as CPE
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@181 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-25 00:36:34 +00:00
Mark Spencer
3cfff2fe15 Fix switch compatibility issue with STATUS and S-12 switch (bug #3415)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@180 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-24 20:57:04 +00:00
Mark Spencer
c05e4b45c0 Merge pcadach's new progress code (bug #2822)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@179 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-17 12:58:05 +00:00
Mark Spencer
1630193827 Fix Makefile for update to be better (bug #3284)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@176 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-01-09 01:18:22 +00:00
Matthew Fredrickson
073bd4fa70 Support callername being sent over NI2 type switches
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@175 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-27 16:25:29 +00:00
Matthew Fredrickson
b210417743 For switches (NI2) that implement GR-1367 callername can't be greater than 15
characters.


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@174 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-27 16:22:30 +00:00
Mark Spencer
7f2237532a Fix for SE-Linux (bug #3147)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@172 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-26 23:10:54 +00:00
Mark Spencer
eb07e6e76c Support original number (bug #3134)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@171 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-23 01:55:51 +00:00
Matthew Fredrickson
610abad23b Mods so that PRI_NETWORK side on NI2 switches sends Callername
over facility IE


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@170 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-22 18:46:23 +00:00
Mark Spencer
ecaf1b6103 Add redirecting reason as a define to detect in chan_zap
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@169 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-16 03:10:41 +00:00
Mark Spencer
a6977c6ddb Complete port to solaris (bug #3062)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@168 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-15 20:15:28 +00:00
Matthew Fredrickson
0f6b3ad8ac Adding redirecting reason support if exists to public interface
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@167 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-15 19:48:15 +00:00
Mark Spencer
77bc439e4a Add support for codeset 6 DISPLAY
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@165 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-15 15:48:20 +00:00
Mark Spencer
e1d6903ed4 Fix order
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@164 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-15 15:44:22 +00:00
Mark Spencer
f0396f6fa5 Fix fputs/fprintf
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@163 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-15 15:43:17 +00:00
Mark Spencer
b75e9f8355 Fix timers issue with GR-303
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@162 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-12-12 22:12:04 +00:00
Mark Spencer
56dc30315b Fix ANI2 support (bug #2788)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@160 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-11-07 18:58:05 +00:00
Mark Spencer
8ae7489b5a Fix ANI II digits (bug #2788)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@159 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-11-05 20:27:56 +00:00
Mark Spencer
2728db0c83 Merge Paul's generic digits support (bug #2788)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@158 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-11-05 02:12:02 +00:00
Mark Spencer
52f8d6bbd9 Minor debugging improvements (bug #2758)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@157 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-30 20:22:04 +00:00
Mark Spencer
b6d1f4016f Add progress support reporting to PRI (bug #2759)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@156 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-30 20:19:18 +00:00
Mark Spencer
5b2bc04f41 Add ability to send redirecting number (bug #2760)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@155 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-30 20:13:20 +00:00
Mark Spencer
660a6a7754 Don't be picky about PROGRESS having PROGRESS INDICATOR.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@154 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-29 15:41:59 +00:00
Matthew Fredrickson
69e8d42ac2 Change to which switchtypes to send facility IEs to
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@152 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-28 16:18:14 +00:00
Matthew Fredrickson
8a5895191f Adding some new files for handling facility ies
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@151 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-27 20:44:39 +00:00
Matthew Fredrickson
cea480c941 Rudimentery support for transmitting and receiving calling name
via facility information elements


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@150 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-27 20:43:23 +00:00
Mark Spencer
6bfef709dc Fix endian for FreeBSD (bug #2679)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@149 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-27 20:17:17 +00:00
James Golovich
542a5ffe0c Change pri_dump_info to generate string instead of using pri_message (bug 2703)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@147 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-26 04:27:29 +00:00
Mark Spencer
a3101da9fe Documentation fixes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@142 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-14 18:23:47 +00:00
Mark Spencer
8ac2db33d4 Add missing case in pres2str (bug #2567)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@139 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-04 14:41:02 +00:00
James Golovich
ba5a5ca907 Allow PRI timers to be congfigurable. (bug 2518)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@138 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-10-02 14:55:20 +00:00
Mark Spencer
2b7b7e2e68 Make sure retranstimer is set to 0
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@135 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-20 13:29:37 +00:00
Mark Spencer
9682be31fb Merge BKW's ANI2 patch (bug #2450)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@134 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-17 04:02:16 +00:00
Mark Spencer
ea146a8f6f Check for existance of *caller* number when sending caller, not called number (bug #2453)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@133 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-16 20:38:13 +00:00
Mark Spencer
12155fa6c3 Minor Makefile fixes for libpri (bug #2330)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@132 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-08-31 17:40:59 +00:00
Mark Spencer
96535a0c17 Fix redirecting number (bug #2146)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@131 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-08-25 06:20:50 +00:00
Mark Spencer
cac414333f Matt's requested fix
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@130 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-23 16:20:06 +00:00
Mark Spencer
748702c5c5 Don't seg when out of memory (bug #2120)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@129 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-23 16:04:01 +00:00
Mark Spencer
6dd859f5de Don't process subchannels by default
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@128 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-16 02:14:04 +00:00
Mark Spencer
5fd79b6b1b Add notify patch (bug #1785)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@127 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 17:57:18 +00:00
James Golovich
e88ac71b3d Make mkdep throw away stderr
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@126 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 15:19:15 +00:00
Mark Spencer
5166adfb1e Never send channel identifier with SETUP when GR303 CPE
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@125 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 04:28:34 +00:00
Mark Spencer
f8b7c404a0 Don't expect connect acknowledge on CPE when GR-303 mode
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@124 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-27 20:29:53 +00:00
Mark Spencer
b93317f38b Make sure NSF is initialized properly
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@123 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-26 04:42:20 +00:00
Mark Spencer
18958fa7e8 Add NSF support (bug #1927)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@122 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-26 04:37:09 +00:00
Mark Spencer
c9bb969586 Add subaddress support
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@121 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-25 19:33:12 +00:00
Mark Spencer
7cdd6c7f2c Don't send Character set in EuroISDN
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@120 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-24 13:43:36 +00:00
Mark Spencer
3193d779ef Don't change states on progress!
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@119 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-17 16:24:10 +00:00
Mark Spencer
97648bb1b4 Handle DISC and REL with missing mandatory information elements
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@118 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 22:19:11 +00:00
Mark Spencer
20e146406b More codeset fixes (thanks to pcadach)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@117 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 18:25:35 +00:00
Mark Spencer
1e5fad5fe7 Don't send proceeding when sending progress
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@116 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 18:04:22 +00:00
Mark Spencer
dd9ba5b8a5 Allow number complete to be forced on SETUP
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@115 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 17:16:37 +00:00
Mark Spencer
d4eab6216e Create new, more extensible setup method (pri_setup)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@114 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 15:33:58 +00:00
Mark Spencer
1cabafb5fb Handle locking and non-locking shift (bug #1687)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@113 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 22:21:05 +00:00
Mark Spencer
66781c3141 Separate PROGRESS and PROCEEDING
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@112 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 21:25:41 +00:00
Mark Spencer
832475b271 Debug improvements (including bug #1784)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@111 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 03:29:19 +00:00
Mark Spencer
6ccb8df101 Add notify support courtesy PCadach
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@110 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 02:48:24 +00:00
Mark Spencer
fd0f41e4a5 Include DS1 number
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@109 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 19:28:14 +00:00
James Golovich
0933575a5d Make q931.c:dump_display build the string first then print it in one command. Fixes remote console ugliness
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@108 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 06:51:01 +00:00
Mark Spencer
818a8cb57a Apprently AT&T uses 0x43 for maintenance messages too
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@107 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 03:57:43 +00:00
Mark Spencer
de0e6ba4cc Formatting fixes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@106 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 17:00:29 +00:00
Mark Spencer
30d983f45f More GR-303 fixes, detect drop of D-channel
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@105 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 15:55:39 +00:00
Mark Spencer
d0c78dd62d Add the ability to slave one PRI to another with respect to calls
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@104 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 03:33:51 +00:00
Mark Spencer
551f0fafc8 Be careful not to destroy non-existant calls
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@103 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-06 23:26:43 +00:00
Mark Spencer
2300f57294 GR-303 updates
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@102 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-06 01:21:41 +00:00
Mark Spencer
f065327cc1 Major changes in preparation for GR-303 and NFAS support
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@101 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-05 06:50:55 +00:00
Mark Spencer
bce8bfb87f Fix minor typo (bug #1701)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@100 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-22 19:06:54 +00:00
Mark Spencer
4ae8cc7bcf Make build on FreeBSD
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@99 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-22 04:25:53 +00:00
Mark Spencer
76955b74c3 Properly handle non-transmission of channel identifier
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@98 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-20 00:21:16 +00:00
Mark Spencer
baefdcb18d Fix debugging of calling party number when no presentation specified (bug #1677)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@97 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 22:02:40 +00:00
Mark Spencer
7aac157b7f Only send channel identifier with call proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@96 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 21:01:36 +00:00
Mark Spencer
2c26d98a89 Add separate ability to do both progress and proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@95 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:34:43 +00:00
Mark Spencer
c413151375 Send progress indicator on progress if appropriate
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@94 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:26:16 +00:00
Mark Spencer
8098266c90 Allow progress to be sent with 1
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@93 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:21:15 +00:00
Mark Spencer
c8528b633a Allow ability to send just call proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@92 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 14:34:29 +00:00
Mark Spencer
c591726079 We have to update n_r when transmitting backlogged packets
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@91 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-17 03:32:11 +00:00
James Golovich
9f724a22f3 Extremely minor q931.c code cleanup
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@90 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-21 21:21:29 +00:00
Mark Spencer
c39fdd5cad On EuroISDN don't send layer1/2 since some switches seem to be concerned. (bug #960)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@89 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-16 18:05:41 +00:00
Mark Spencer
f2eb8afb7f Revert jcdutton's changes which are not subject to be disclaimed
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@87 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-11 01:55:54 +00:00
Mark Spencer
8da0a1e5a7 Debug improvements (bug #1329)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@86 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-11 01:27:11 +00:00
Mark Spencer
4743ebd26f Generate release complete message back to Asterisk when T308 expires twice.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@85 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-06 14:50:19 +00:00
James Golovich
949afd2385 Format q921 log string before printing. Fixes those annoying half patch
packet decodes when logging data with something like script or tee


git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@84 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-05 08:22:14 +00:00
James Golovich
480160c5cf Add .cvsignore to libpri
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@83 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-04 21:44:38 +00:00
James Golovich
2f5952fa86 Make pri_switch2str know about EuroISDN (bug 1348)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@82 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-04 21:41:43 +00:00
James Golovich
be3a8c206b Add mkdep and 'make depend' to libpri Makefile
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@81 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-03-30 20:18:12 +00:00
James Golovich
ee394a7916 Make pri_dump_info print newly added pri->windowlen
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@80 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-03-29 09:18:38 +00:00
Mark Spencer
91b4a60c1f Add test program for windowing, implement proper windowing
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@79 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-03-29 08:09:01 +00:00
James Golovich
d00abddee3 Add pri_dump_info and q921/q931 counters to libpri
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@78 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-03-15 05:53:25 +00:00
Mark Spencer
09645488d6 Don't send release complete on the global call identifier
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@77 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-02-25 20:02:04 +00:00
Mark Spencer
24fba7f9b7 If userl1 is -1, don't include it
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@76 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-02-08 00:20:18 +00:00
Mark Spencer
c3544cb866 Add uninstall target
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@75 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-02-02 05:55:03 +00:00
Martin Pycko
ccafdd739b Add displaying User to User messages (the 2nd part of Bug #289)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@74 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-01-28 21:02:23 +00:00
Mark Spencer
acf0e055ab Makefile fixes (bug #923)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@73 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-01-27 00:39:59 +00:00
Mark Spencer
e1394704ad Fix SERVICE_ACKNOWLEDGE even with different address sizes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@71 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-01-17 15:14:11 +00:00
Martin Pycko
0961ecb4b0 Don't expect CONNECT_ACK after we send CONNECT if we're the network and they're the user.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@70 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-12-09 15:55:48 +00:00
Martin Pycko
a36186ce49 Don't reject SETUP without missing channel information IE if we're network.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@69 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-12-05 23:10:33 +00:00
Mark Spencer
5f6e12c3e5 Populate ctype field
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@68 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-11-24 14:36:46 +00:00
Mark Spencer
d80324dbdd Ignore invalid/non Q.931 protocol discriminator
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@67 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-11-19 20:11:11 +00:00
Mark Spencer
e172ca2a03 Accept "PROGRESS" after "ALERTING"
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@66 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-15 13:56:10 +00:00
Mark Spencer
e4f9ea7583 Accept "PROGRESS" after "ALERTING"
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@65 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-15 13:56:09 +00:00
Martin Pycko
b5fa5986b2 Forgot to put break in the last patch
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@64 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-13 22:36:07 +00:00
Martin Pycko
f63cc76a94 Allow the reception of 1 byte Call Reference value
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@63 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-13 22:34:05 +00:00
Mark Spencer
cb01262a54 Progress OK when "CALL PROCEEDING"
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@62 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-10 07:04:19 +00:00
Mark Spencer
79e10c30a1 Fix for new GCC's
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@61 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-10-06 05:15:16 +00:00
Mark Spencer
06d9c2aeb3 Bring into full TBR4 compliance
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@60 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-09-25 06:13:14 +00:00
Martin Pycko
4e6c9e0410 Fix q931_hangup for (call received, call delivered)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@58 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-09-09 23:49:10 +00:00
Martin Pycko
88656d9497 Don't reset peercallstate when we receive the STATUS message
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@57 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-09-09 23:40:16 +00:00
Martin Pycko
fe0eba8175 Fix the displaying of the information about the ANI/callerid
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@56 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-13 03:08:22 +00:00
Martin Pycko
24b85a379b Add pri_destroycall
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@55 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-12 20:16:55 +00:00
Martin Pycko
ec99ad86dd Regarding the new pri hangup: rewrite a little bit and introduce the PRI_EVENT_HANGUP_REQ
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@54 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-07 00:45:04 +00:00
Martin Pycko
ee9ef9ef3c One last thing fixed so that libpri would compile on 'other' systems
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@53 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-06 16:53:40 +00:00
Martin Pycko
f6966bc35b Fix the compilation errors on some systems due to -Werror flag
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@52 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-06 15:20:49 +00:00
Martin Pycko
45efb97ebd Update q931_hangup routine
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@51 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 20:37:32 +00:00
Martin Pycko
110062aef6 Allow to send the CAUSE IE along with RELEASE_COMPLETE message
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@50 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 19:26:07 +00:00
Martin Pycko
de24dd76a6 Send RELEASE COMPLETE if the cause is UNALLOCATED NUMBER (1) instead of sending DISCONNECT (although that should be ok too)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@49 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 18:42:55 +00:00
Martin Pycko
e09654f0ed Allow the use of pri_release and pri_disconnect to have backwards compatibility for those who don't use asterisk with libpri
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@48 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 01:20:25 +00:00
Martin Pycko
86fe59eacc Make dependencies between asterisk and libpri using the flag PRI_HANGUP
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@47 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 01:08:06 +00:00
Martin Pycko
2809056303 Fix and improve (based on callstates) the hangup routines
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@46 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-08-05 01:00:45 +00:00
Mark Spencer
f8d3569b56 Handle sendingcomplete properly
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@45 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-07-26 15:14:44 +00:00
Martin Pycko
5f1aba027a Add posibility of choosing a diffrent form of ALERTING messages that has to be changed to work e.g. with Mitel switches.
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@44 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-07-07 23:37:18 +00:00
Mark Spencer
a85d2c508b Handle sending complete
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@43 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-07-01 20:25:34 +00:00
Martin Pycko
34f700b584 Change the way we store the callednum from INFORMATION messages
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@42 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-06-05 21:15:56 +00:00
Mark Spencer
5137d733f9 Add National ISDN 1 switchtype
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@41 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-05-28 22:34:59 +00:00
Martin Pycko
5478d68b2a Pass the info about SETUP_ACKNOWLEDGE outside libpri
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@40 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-05-15 22:15:38 +00:00
Martin Pycko
6e8e051464 Don't send IE field 'Sending Complete' when we want to do overlap dialing (sending)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@39 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-05-15 19:35:05 +00:00
Mark Spencer
80355d96c5 Don't automatically send release
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@38 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-05-12 16:59:12 +00:00
Martin Pycko
e4d3ca388b Add PRI_EVENT_PROCEEDING when we get CALL_PROCEEDING or PROGRESS
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@37 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-04-18 15:56:38 +00:00
Martin Pycko
426336f4e6 Don't use a function call in pri_information
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@35 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-03-25 17:02:23 +00:00
Martin Pycko
af1366fcde Add sending INFORMATION messages
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@34 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-03-24 21:52:51 +00:00
Matteo Brancaleoni
96695361e4 Wed Mar 19 07:00:01 CET 2003
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@33 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-03-19 06:00:31 +00:00
Matteo Brancaleoni
cc7adcd328 Wed Mar 5 07:00:00 CET 2003
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@32 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-03-05 06:00:35 +00:00
Matteo Brancaleoni
2a1c974412 Tue Mar 4 07:00:01 CET 2003
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@31 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-03-04 06:00:37 +00:00
Matteo Brancaleoni
b00db5738c mar feb 18 19:15:15 CET 2003
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@30 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-02-18 18:15:47 +00:00
Matteo Brancaleoni
c0ce1c85ed mer feb 12 14:56:57 CET 2003
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@29 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2003-02-12 13:59:23 +00:00
23 changed files with 6617 additions and 753 deletions

43
ChangeLog Executable file → Normal file
View File

@@ -1,16 +1,33 @@
libpri 0.3.0
-- Fix talking to switch
-- Add pri dump
-- Add test application
-- Fix strncpy stuff
libpri 0.1.2
-- Added PRI_EVENT_HANGUP_ACK so you can know when the disconnect was
acknowledged
2006-01-18 Russell Bryant <russell@digium.com>
libpri 0.1.1
-- Added PRI_DEBUG_Q931_ANOMALY flag so that certain non-error-related
messages would not be output unless specifically desired.
* Libpri 1.2.2 Released
2006-01-17 13:43 +0000 [r291] Kevin P. Fleming <kpfleming@digium.com>
* q931.c: ensure that user-user info field in call is properly
reset when not needed
2006-01-10 20:19 +0000 [r290] Matt Frederickson <creslin@digium.com>
* Makefile: Backport of doing correct minor numbers to 1.2 (#6188)
2005-12-27 14:01 +0000 [r284] Matt Frederickson <creslin@digium.com>
* q931.c: Fix for issue #6039 backported to 1.2
2005-12-06 21:35 +0000 [r280] Matt Frederickson <creslin@digium.com>
* q921.c: Send RR as command instead of response when T200 expires
after receiving RNR.
2005-12-01 23:13 +0000 [r274] Kevin P. Fleming <kpfleming@digium.com>
* Makefile: Makefile 'update' target now supports Subversion
repositories (issue #5875)
2005-12-01 02:34 +0000 [r270] Matt Frederickson <creslin@digium.com>
* q931.c: Backport of fix from trunk. Fix broken single digit
keypad facility code.
libpri 0.1.0
-- Initial release

341
LICENSE Normal file
View File

@@ -0,0 +1,341 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

121
Makefile Executable file → Normal file
View File

@@ -20,29 +20,106 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
# Uncomment if you want libpri not send PROGRESS_INDICATOR w/ALERTING
#ALERTING=-DALERTING_NO_PROGRESS
# Uncomment if you want libpri to count number of Q921/Q931 sent/received
#LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
CC=gcc
OSARCH=$(shell uname -s)
PROC?=$(shell uname -m)
TOBJS=testpri.o
T2OBJS=testprilib.o
STATIC_LIBRARY=libpri.a
DYNAMIC_LIBRARY=libpri.so.1.0
STATIC_OBJS=pri.o q921.o prisched.o q931.o
DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g
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?=
INSTALL_BASE=/usr
SOFLAGS = -Wl,-hlibpri.so.1.0
LDCONFIG = /sbin/ldconfig
ifeq (${OSARCH},Linux)
LDCONFIG_FLAGS=-n
else
ifeq (${OSARCH},FreeBSD)
LDCONFIG_FLAGS=-m
CFLAGS += -I../zaptel -I../zapata
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
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
#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.
ifeq ($(PROC),sparc64)
PROC=ultrasparc
CFLAGS += -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
endif
all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
update:
@if [ -d .svn ]; then \
echo "Updating from Subversion..." ; \
svn update -q; \
elif [ -d CVS ]; then \
echo "Updating from CVS..." ; \
cvs -q -z3 update -Pd; \
else \
echo "Not under version control"; \
fi
install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
mkdir -p /usr/lib
mkdir -p /usr/include
install -m 644 libpri.h /usr/include
install -m 755 $(DYNAMIC_LIBRARY) /usr/lib
( cd /usr/lib ; ln -sf libpri.so.1 libpri.so )
install -m 644 $(STATIC_LIBRARY) /usr/lib
/sbin/ldconfig
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/include
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 restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
( 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); 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.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.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
pritest: pritest.o
$(CC) -o pritest pritest.o -L. -lpri -lzap
$(CC) -o pritest pritest.o -L. -lpri -lzap $(CFLAGS)
testprilib.o: testprilib.c
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE -o $@ -c $<
testprilib: testprilib.o
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
pridump: pridump.o
$(CC) -o pridump pridump.o -L. -lpri -lzap
$(CC) -o pridump pridump.o -L. -lpri $(CFLAGS)
ifneq ($(wildcard .depend),)
include .depend
endif
%.lo : %.c
$(CC) -fPIC $(CFLAGS) -o $@ -c $<
@@ -52,11 +129,19 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
ranlib $(STATIC_LIBRARY)
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
$(CC) -shared -Wl,-soname,libpri.so.1 -o $@ $(DYNAMIC_OBJS)
/sbin/ldconfig -n .
ln -sf libpri.so.1 libpri.so
$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
$(LDCONFIG) $(LDCONFIG_FLAGS) .
ln -sf libpri.so.1.0 libpri.so
ln -sf libpri.so.1.0 libpri.so.1
$(SOSLINK)
clean:
rm -f *.o *.so *.lo
rm -f testpri $(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`

28
README Executable file → Normal file
View File

@@ -1,31 +1,45 @@
libpri: An implementation of Primate Rate ISDN
Written by Mark Spencer <markster@linux-support.net>
Written by Mark Spencer <markster@digium.com>
What is libpri?
===============
libpri is a C implementation of the Primary Rate ISDN specification. It was
based on the Bellcore specification SR-NWT-002343 for National ISDN. As of
May 12, 2001, it has been tested work with NI-2, Nortel DMS-100, and Lucent 5E Custom protocols on switches from Nortel and Lucent.
May 12, 2001, it has been tested work with NI-2, Nortel DMS-100, and
Lucent 5E Custom protocols on switches from Nortel and Lucent.
What is the license for libpri?
===============================
libpri is distributed under the terms of the GNU General Public License, which permit its use and linking with other GPL'd software only.
libpri is distributed under the terms of the GNU General Public License,
which permit its use and linking with other GPL'd software only.
The GNU GPL is included in the file LICENSE in this directory.
As a special exception, libpri may also be linked to the OpenH323
library, so long as the entirity of the derivative work (as defined
within the GPL) is licensed either under the MPL of the OpenH323 license
or the GPL of libpri.
If you wish to use libpri in an application for which the GPL is not
appropriate (e.g. a proprietary embedded system), licenses for libpri
under more flexible terms can be readily obtained through Digium, Inc.
at reasonable cost.
If you wish to use libpri in an application for which the GPL is not appropriate (e.g. a proprietary embedded system), licenses for libpri under more flexible terms can be readily obtained through Linux Support Services, Inc. at reasonable cost.
How do I report bugs or contribute?
===================================
For now, contact the author directly. In the future if there is sufficient interest, we will setup a mailing list.
For now, contact the author directly. In the future if there is
sufficient interest, we will setup a mailing list.
Does anything use this library so far?
======================================
Yes, the Asterisk Open Source PBX does. http://www.asteriskpbx.com
Yes, the Asterisk Open Source PBX does. http://www.asterisk.org
Also, the Zapata library has hooks for it. http://www.zapatatelephony.org
Special thanks
==============
Special thanks to Jim Dixon <jim@lambdatel.com> for his help in testing and fixing the implementation.
Special thanks to Jim Dixon <jim@lambdatel.com> for his help in
testing and fixing the implementation.

0
TODO Executable file → Normal file
View File

10
compat.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef __COMPAT_H
#define __COMPAT_H
#ifdef SOLARIS
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
#endif
#endif

19
compiler.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Compiler-specific macros and other items
*
* Copyright (C) 2005, Digium, Inc.
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#ifndef _ASTERISK_COMPILER_H
#define _ASTERISK_COMPILER_H
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
#define __builtin_expect(exp, c) (exp)
#endif
#endif /* _ASTERISK_COMPILER_H */

42
copy_string.c Normal file
View File

@@ -0,0 +1,42 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "compiler.h"
#include "libpri.h"
#include "pri_internal.h"
void libpri_copy_string(char *dst, const char *src, size_t size)
{
while (*src && size) {
*dst++ = *src++;
size--;
}
if (__builtin_expect(!size, 0))
dst--;
*dst = '\0';
}

348
libpri.h Executable file → Normal file
View File

@@ -37,6 +37,8 @@
#define PRI_DEBUG_Q931_DUMP (1 << 5) /* Show interpreted Q.931 frames */
#define PRI_DEBUG_Q931_STATE (1 << 6) /* Debug Q.931 state machine changes */
#define PRI_DEBUG_Q931_ANOMALY (1 << 7) /* Show unexpected events */
#define PRI_DEBUG_APDU (1 << 8) /* Debug of APDU components such as ROSE */
#define PRI_DEBUG_AOC (1 << 9) /* Debug of Advice of Charge ROSE Messages */
#define PRI_DEBUG_ALL (0xffff) /* Everything */
@@ -46,25 +48,53 @@
#define PRI_SWITCH_DMS100 2 /* DMS 100 */
#define PRI_SWITCH_LUCENT5E 3 /* Lucent 5E */
#define PRI_SWITCH_ATT4ESS 4 /* AT&T 4ESS */
#define PRI_SWITCH_EUROISDN_E1 5 /* Standard EuroISDN (CTR4, ETSI 300-102) */
#define PRI_SWITCH_EUROISDN_T1 6 /* T1 EuroISDN variant (ETSI 300-102) */
#define PRI_SWITCH_EUROISDN_E1 5 /* Standard EuroISDN (CTR4, ETSI 300-102) */
#define PRI_SWITCH_EUROISDN_T1 6 /* T1 EuroISDN variant (ETSI 300-102) */
#define PRI_SWITCH_NI1 7 /* National ISDN 1 */
#define PRI_SWITCH_GR303_EOC 8 /* GR-303 Embedded Operations Channel */
#define PRI_SWITCH_GR303_TMC 9 /* GR-303 Timeslot Management Channel */
#define PRI_SWITCH_QSIG 10 /* QSIG Switch */
/* Switchtypes 11 - 20 are reserved for internal use */
/* PRI D-Channel Events */
#define PRI_EVENT_DCHAN_UP 1 /* D-channel is up */
#define PRI_EVENT_DCHAN_DOWN 2 /* D-channel is down */
#define PRI_EVENT_RESTART 3 /* B-channel is restarted */
#define PRI_EVENT_CONFIG_ERR 4 /* Configuration Error Detected */
#define PRI_EVENT_RING 5 /* Incoming call */
#define PRI_EVENT_HANGUP 6 /* Call got hung up */
#define PRI_EVENT_RINGING 7 /* Call is ringing (alerting) */
#define PRI_EVENT_ANSWER 8 /* Call has been answered */
#define PRI_EVENT_HANGUP_ACK 9 /* Call hangup has been acknowledged */
#define PRI_EVENT_DCHAN_UP 1 /* D-channel is up */
#define PRI_EVENT_DCHAN_DOWN 2 /* D-channel is down */
#define PRI_EVENT_RESTART 3 /* B-channel is restarted */
#define PRI_EVENT_CONFIG_ERR 4 /* Configuration Error Detected */
#define PRI_EVENT_RING 5 /* Incoming call */
#define PRI_EVENT_HANGUP 6 /* Call got hung up */
#define PRI_EVENT_RINGING 7 /* Call is ringing (alerting) */
#define PRI_EVENT_ANSWER 8 /* Call has been answered */
#define PRI_EVENT_HANGUP_ACK 9 /* Call hangup has been acknowledged */
#define PRI_EVENT_RESTART_ACK 10 /* Restart complete on a given channel */
#define PRI_EVENT_FACNAME 11 /* Caller*ID Name received on Facility */
#define PRI_EVENT_INFO_RECEIVED 12 /* Additional info (keypad) received */
#define PRI_EVENT_PROCEEDING 13 /* When we get CALL_PROCEEDING or PROGRESS */
#define PRI_EVENT_SETUP_ACK 14 /* When we get SETUP_ACKNOWLEDGE */
#define PRI_EVENT_HANGUP_REQ 15 /* Requesting the higher layer to hangup */
#define PRI_EVENT_NOTIFY 16 /* Notification received */
#define PRI_EVENT_PROGRESS 17 /* When we get CALL_PROCEEDING or PROGRESS */
#define PRI_EVENT_KEYPAD_DIGIT 18 /* When we receive during ACTIVE state */
/* Simple states */
#define PRI_STATE_DOWN 0
#define PRI_STATE_UP 1
#define PRI_PROGRESS_MASK
/* Progress indicator values */
#define PRI_PROG_CALL_NOT_E2E_ISDN (1 << 0)
#define PRI_PROG_CALLED_NOT_ISDN (1 << 1)
#define PRI_PROG_CALLER_NOT_ISDN (1 << 2)
#define PRI_PROG_INBAND_AVAILABLE (1 << 3)
#define PRI_PROG_DELAY_AT_INTERF (1 << 4)
#define PRI_PROG_INTERWORKING_WITH_PUBLIC (1 << 5)
#define PRI_PROG_INTERWORKING_NO_RELEASE (1 << 6)
#define PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER (1 << 7)
#define PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER (1 << 8)
#define PRI_PROG_CALLER_RETURNED_TO_ISDN (1 << 9)
/* Numbering plan identifier */
#define PRI_NPI_UNKNOWN 0x0
#define PRI_NPI_E163_E164 0x1
@@ -161,7 +191,8 @@
#define PRI_TRANS_CAP_DIGITAL 0x08
#define PRI_TRANS_CAP_RESTRICTED_DIGITAL 0x09
#define PRI_TRANS_CAP_3_1K_AUDIO 0x10
#define PRI_TRANS_CAP_7K_AUDIO 0x11
#define PRI_TRANS_CAP_7K_AUDIO 0x11 /* Depriciated ITU Q.931 (05/1998)*/
#define PRI_TRANS_CAP_DIGITAL_W_TONES 0x11
#define PRI_TRANS_CAP_VIDEO 0x18
#define PRI_LAYER_1_ITU_RATE_ADAPT 0x21
@@ -174,6 +205,51 @@
#define PRI_LAYER_1_V120_RATE_ADAPT 0x28
#define PRI_LAYER_1_X31_RATE_ADAPT 0x29
/* Notifications */
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */
#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */
#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */
#define PRI_NOTIFY_CONF_ESTABLISHED 0x42 /* Conference established */
#define PRI_NOTIFY_CONF_DISCONNECTED 0x43 /* Conference disconnected */
#define PRI_NOTIFY_CONF_PARTY_ADDED 0x44 /* Other party added */
#define PRI_NOTIFY_CONF_ISOLATED 0x45 /* Isolated */
#define PRI_NOTIFY_CONF_REATTACHED 0x46 /* Reattached */
#define PRI_NOTIFY_CONF_OTHER_ISOLATED 0x47 /* Other party isolated */
#define PRI_NOTIFY_CONF_OTHER_REATTACHED 0x48 /* Other party reattached */
#define PRI_NOTIFY_CONF_OTHER_SPLIT 0x49 /* Other party split */
#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */
#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */
#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */
#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */
#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */
#define PRI_COPY_DIGITS_CALLED_NUMBER
/* Network Specific Facilities (AT&T) */
#define PRI_NSF_NONE -1
#define PRI_NSF_SID_PREFERRED 0xB1
#define PRI_NSF_ANI_PREFERRED 0xB2
#define PRI_NSF_SID_ONLY 0xB3
#define PRI_NSF_ANI_ONLY 0xB4
#define PRI_NSF_CALL_ASSOC_TSC 0xB9
#define PRI_NSF_NOTIF_CATSC_CLEARING 0xBA
#define PRI_NSF_OPERATOR 0xB5
#define PRI_NSF_PCCO 0xB6
#define PRI_NSF_SDN 0xE1
#define PRI_NSF_TOLL_FREE_MEGACOM 0xE2
#define PRI_NSF_MEGACOM 0xE3
#define PRI_NSF_ACCUNET 0xE6
#define PRI_NSF_LONG_DISTANCE_SERVICE 0xE7
#define PRI_NSF_INTERNATIONAL_TOLL_FREE 0xE8
#define PRI_NSF_ATT_MULTIQUEST 0xF0
#define PRI_NSF_CALL_REDIRECTION_SERVICE 0xF7
typedef struct q931_call q931_call;
typedef struct pri_event_generic {
@@ -195,29 +271,63 @@ typedef struct pri_event_ringing {
int e;
int channel;
int cref;
int progress;
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
} pri_event_ringing;
typedef struct pri_event_answer {
int e;
int channel;
int cref;
int progress;
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
} pri_event_answer;
typedef struct pri_event_facname {
int e;
char callingname[256];
char callingnum[256];
int channel;
int cref;
q931_call *call;
} pri_event_facname;
#define PRI_CALLINGPLANANI
#define PRI_CALLINGPLANRDNIS
typedef struct pri_event_ring {
int e;
int channel; /* Channel requested */
int callingpres; /* Presentation of Calling CallerID */
int callingplanani; /* Dialing plan of Calling entity ANI */
int callingplan; /* Dialing plan of Calling entity */
char callingani[256]; /* Calling ANI */
char callingnum[256]; /* Calling number */
char callingname[256]; /* Calling name (if provided) */
int calledplan; /* Dialing plan of Called number */
int ani2; /* ANI II */
char callednum[256]; /* Called number */
char redirectingnum[256]; /* Redirecting number */
char redirectingname[256]; /* Redirecting name */
int redirectingreason; /* Reason for redirect */
int callingplanrdnis; /* Dialing plan of Redirecting Number */
char useruserinfo[260]; /* User->User info */
int flexible; /* Are we flexible with our channel selection? */
int cref; /* Call Reference Number */
int ctype; /* Call type (see PRI_TRANS_CAP_* */
int layer1; /* User layer 1 */
int layer1; /* User layer 1 */
int complete; /* Have we seen "Complete" i.e. no more number? */
q931_call *call; /* Opaque call pointer */
char callingsubaddr[256]; /* Calling parties subaddress */
int progress;
int progressmask;
char origcalledname[256];
char origcallednum[256];
int callingplanorigcalled; /* Dialing plan of Originally Called Number */
int origredirectingreason;
} pri_event_ring;
typedef struct pri_event_hangup {
@@ -226,6 +336,8 @@ typedef struct pri_event_hangup {
int cause;
int cref;
q931_call *call; /* Opaque call pointer */
long aoc_units; /* Advise of Charge number of charged units */
char useruserinfo[260]; /* User->User info */
} pri_event_hangup;
typedef struct pri_event_restart_ack {
@@ -233,20 +345,58 @@ typedef struct pri_event_restart_ack {
int channel;
} pri_event_restart_ack;
#define PRI_PROGRESS_CAUSE
typedef struct pri_event_proceeding {
int e;
int channel;
int cref;
int progress;
int progressmask;
int cause;
q931_call *call;
} pri_event_proceeding;
typedef struct pri_event_setup_ack {
int e;
int channel;
} pri_event_setup_ack;
typedef struct pri_event_notify {
int e;
int channel;
int info;
} pri_event_notify;
typedef struct pri_event_keypad_digit {
int e;
int channel;
q931_call *call;
char digits[64];
} pri_event_keypad_digit;
typedef union {
int e;
pri_event_generic gen; /* Generic view */
pri_event_restart restart; /* Restart view */
pri_event_error err; /* Error view */
pri_event_facname facname; /* Caller*ID Name on Facility */
pri_event_ring ring; /* Ring */
pri_event_hangup hangup; /* Hang up */
pri_event_ringing ringing; /* Ringing */
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 */
pri_event_notify notify; /* Notification */
pri_event_keypad_digit digit; /* Digits that come during a call */
} pri_event;
struct pri;
struct pri_sr;
#define PRI_IO_FUNCS
/* Type declaration for callbacks to read or write a HDLC frame as below */
typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen);
/* Create a D-channel on a given file descriptor. The file descriptor must be a
channel operating in HDLC mode with FCS computed by the fd's driver. Also it
@@ -254,9 +404,28 @@ struct pri;
must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */
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 */
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 */
extern void *pri_get_userdata(struct pri *pri);
/* Set the user data associated with the D channel */
extern void pri_set_userdata(struct pri *pri, void *userdata);
/* Set Network Specific Facility for PRI */
extern void pri_set_nsf(struct pri *pri, int nsf);
/* Set debug parameters on PRI -- see above debug definitions */
extern void pri_set_debug(struct pri *pri, int debug);
/* Get debug parameters on PRI -- see above debug definitions */
extern int pri_get_debug(struct pri *pri);
#define PRI_FACILITY_ENABLE
/* Enable transmission support of Facility IEs on the 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 */
@@ -268,7 +437,7 @@ pri_event *pri_check_event(struct pri *pri);
/* Give a name to a given event ID */
extern char *pri_event2str(int id);
/* Give a name toa node type */
/* Give a name to a node type */
extern char *pri_node2str(int id);
/* Give a name to a switch type */
@@ -277,9 +446,6 @@ extern char *pri_switch2str(int id);
/* Print an event */
extern void pri_dump_event(struct pri *pri, pri_event *e);
/* Turn an event ID into a string */
extern char *pri_event2str(int e);
/* Turn presentation into a string */
extern char *pri_pres2str(int pres);
@@ -293,21 +459,51 @@ extern char *pri_cause2str(int cause);
is in-band data available on the channel */
extern int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
/* Send a digit in overlap mode */
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 */
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 */
extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
/* Release/Reject a call */
extern int pri_release(struct pri *pri, q931_call *call, int cause);
/* Set CRV reference for GR-303 calls */
/* Hangup / Disconnect a call */
extern int pri_disconnect(struct pri *pri, q931_call *call, int cause);
#undef pri_release
#undef pri_disconnect
/* backwards compatibility for those who don't use asterisk with libpri */
#define pri_release(a,b,c) \
pri_hangup(a,b,c)
#define pri_disconnect(a,b,c) \
pri_hangup(a,b,c)
/* Hangup a call */
#define PRI_HANGUP
extern int pri_hangup(struct pri *pri, q931_call *call, int cause);
#define PRI_DESTROYCALL
extern void pri_destroycall(struct pri *pri, q931_call *call);
#define PRI_RESTART
extern int pri_restart(struct pri *pri);
extern int pri_reset(struct pri *pri, int channel);
/* Create a new call */
extern q931_call *pri_new_call(struct pri *pri);
/* Retrieve CRV reference for GR-303 calls. Returns >0 on success. */
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 */
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 */
extern struct timeval *pri_schedule_next(struct pri *pri);
@@ -315,6 +511,114 @@ extern struct timeval *pri_schedule_next(struct pri *pri);
extern pri_event *pri_schedule_run(struct pri *pri);
extern int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
int exclusive, int nonisdn, char *caller, int callerplan, int callerpres,
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
char *called,int calledplan, int ulayer1);
extern struct pri_sr *pri_sr_new(void);
extern void pri_sr_free(struct pri_sr *sr);
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 */
extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars);
extern void pri_call_set_useruser(q931_call *sr, char *userchars);
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) */
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 */
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 */
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
* suscribed. Sometimes called 2 bchannel transfer (2BCT) */
int pri_channel_bridge(q931_call *call1, q931_call *call2);
/* Override message and error stuff */
#define PRI_NEW_SET_API
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
extern void pri_set_overlapdial(struct pri *pri,int state);
#define PRI_DUMP_INFO_STR
extern char *pri_dump_info_str(struct pri *pri);
/* Get file descriptor */
extern int pri_fd(struct pri *pri);
#define PRI_PROGRESS
/* Send call proceeding */
extern int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
#define PRI_PROCEEDING_FULL
/* Send call proceeding */
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) */
extern void pri_enslave(struct pri *master, struct pri *slave);
#define PRI_GR303_SUPPORT
#define PRI_ENSLAVE_SUPPORT
#define PRI_SETUP_CALL
#define PRI_RECEIVE_SUBADDR
#define PRI_REDIRECTING_REASON
#define PRI_AOC_UNITS
#define PRI_ANI
/* Send notification */
extern int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
/* Get/Set PRI Timers */
#define PRI_GETSET_TIMERS
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_T200 4 /* time between SABME's */
#define PRI_TIMER_T201 5 /* minimum time between retransmissions of the TEI Identity check messages */
#define PRI_TIMER_T202 6 /* minimum time between transmission of TEI Identity request messages */
#define PRI_TIMER_T203 7 /* maxiumum time without exchanging packets */
#define PRI_TIMER_T300 8
#define PRI_TIMER_T301 9 /* maximum time to respond to an ALERT */
#define PRI_TIMER_T302 10
#define PRI_TIMER_T303 11 /* maximum time to wait after sending a SETUP without a response */
#define PRI_TIMER_T304 12
#define PRI_TIMER_T305 13
#define PRI_TIMER_T306 14
#define PRI_TIMER_T307 15
#define PRI_TIMER_T308 16
#define PRI_TIMER_T309 17
#define PRI_TIMER_T310 18 /* maximum time between receiving a CALLPROCEEDING and receiving a ALERT/CONNECT/DISCONNECT/PROGRESS */
#define PRI_TIMER_T313 19
#define PRI_TIMER_T314 20
#define PRI_TIMER_T316 21 /* maximum time between transmitting a RESTART and receiving a RESTART ACK */
#define PRI_TIMER_T317 22
#define PRI_TIMER_T318 23
#define PRI_TIMER_T319 24
#define PRI_TIMER_T320 25
#define PRI_TIMER_T321 26
#define PRI_TIMER_T322 27
#endif

125
mkdep Executable file
View File

@@ -0,0 +1,125 @@
#!/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 $
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mkdep.gcc.sh 8.1 (Berkeley) 6/6/93
#
D=.depend # default dependency file is .depend
append=0
pflag=
while :
do case "$1" in
# -a appends to the depend file
-a)
append=1
shift ;;
# -f allows you to select a makefile name
-f)
D=$2
shift; shift ;;
# the -p flag produces "program: program.c" style dependencies
# so .o's don't get produced
-p)
pflag=p
shift ;;
*)
break ;;
esac
done
if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-f depend_file] [cc_flags] file ...'
exit 1
fi
DTMP=/tmp/mkdep$$
TMP=$DTMP/mkdep
um=`umask`
umask 022
if ! mkdir $DTMP ; then
echo failed to create tmp dir $DTMP
exit 1
fi
umask $um
trap 'rm -rf $DTMP ; trap 2 ; kill -2 $$' 1 2 3 13 15
if [ x$pflag = x ]; then
${CC:-cc} -M "$@" 2>/dev/null | sed -e 's; \./; ;g' > $TMP
else
${CC:-cc} -M "$@" 2>/dev/null | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
fi
if [ $? != 0 ]; then
echo 'mkdep: compile failed.'
rm -rf $DTMP
exit 1
fi
if [ $append = 1 ]; then
cat $TMP >> $D
if [ $? != 0 ]; then
echo 'mkdep: append failed.'
rm -rf $DTMP
exit 1
fi
cat $TMP | sed -e 's/\.o:/.lo:/g' >>$D
if [ $? != 0 ]; then
echo 'mkdep: append failed.'
rm -rf $DTMP
exit 1
fi
else
cat $TMP > $D
if [ $? != 0 ]; then
echo 'mkdep: overwrite failed.'
rm -rf $DTMP
exit 1
fi
cat $TMP | sed -e 's/\.o:/.lo:/g' >>$D
if [ $? != 0 ]; then
echo 'mkdep: append failed.'
rm -rf $DTMP
exit 1
fi
fi
rm -rf $DTMP
exit 0

653
pri.c Executable file → Normal file
View File

@@ -1,13 +1,25 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-suppot.net>
* Written by Mark Spencer <markster@digium.com>
*
* This program is confidential
*
* Copyright (C) 2001, Linux Support Services, Inc.
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <unistd.h>
@@ -18,10 +30,14 @@
#include <unistd.h>
#include <stdlib.h>
#include <sys/select.h>
#include <stdarg.h>
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
#include "pri_facility.h"
#include "pri_q921.h"
#include "pri_q931.h"
#include "pri_timers.h"
char *pri_node2str(int node)
{
@@ -48,27 +64,241 @@ char *pri_switch2str(int sw)
return "Lucent 5E";
case PRI_SWITCH_ATT4ESS:
return "AT&T 4ESS";
case PRI_SWITCH_NI1:
return "National ISDN 1";
case PRI_SWITCH_EUROISDN_E1:
return "EuroISDN";
case PRI_SWITCH_GR303_EOC:
return "GR303 EOC";
case PRI_SWITCH_GR303_TMC:
return "GR303 TMC";
case PRI_SWITCH_QSIG:
return "Q.SIG switch";
default:
return "Unknown switchtype";
}
}
struct pri *pri_new(int fd, int node, int switchtype)
static void pri_default_timers(struct pri *pri, int switchtype)
{
int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
int x;
for (x = 0; x<PRI_MAX_TIMERS; x++) {
pri->timers[x] = defaulttimers[switchtype][x];
}
}
int pri_set_timer(struct pri *pri, int timer, int value)
{
if (timer < 0 || timer > PRI_MAX_TIMERS || value < 0)
return -1;
pri->timers[timer] = value;
return 0;
}
int pri_get_timer(struct pri *pri, int timer)
{
if (timer < 0 || timer > PRI_MAX_TIMERS)
return -1;
return pri->timers[timer];
}
int pri_timer2idx(char *timer)
{
if (!strcasecmp(timer, "N200"))
return PRI_TIMER_N200;
else if (!strcasecmp(timer, "N201"))
return PRI_TIMER_N201;
else if (!strcasecmp(timer, "N202"))
return PRI_TIMER_N202;
else if (!strcasecmp(timer, "K"))
return PRI_TIMER_K;
else if (!strcasecmp(timer, "T200"))
return PRI_TIMER_T200;
else if (!strcasecmp(timer, "T202"))
return PRI_TIMER_T202;
else if (!strcasecmp(timer, "T203"))
return PRI_TIMER_T203;
else if (!strcasecmp(timer, "T300"))
return PRI_TIMER_T300;
else if (!strcasecmp(timer, "T301"))
return PRI_TIMER_T301;
else if (!strcasecmp(timer, "T302"))
return PRI_TIMER_T302;
else if (!strcasecmp(timer, "T303"))
return PRI_TIMER_T303;
else if (!strcasecmp(timer, "T304"))
return PRI_TIMER_T304;
else if (!strcasecmp(timer, "T305"))
return PRI_TIMER_T305;
else if (!strcasecmp(timer, "T306"))
return PRI_TIMER_T306;
else if (!strcasecmp(timer, "T307"))
return PRI_TIMER_T307;
else if (!strcasecmp(timer, "T308"))
return PRI_TIMER_T308;
else if (!strcasecmp(timer, "T309"))
return PRI_TIMER_T309;
else if (!strcasecmp(timer, "T310"))
return PRI_TIMER_T310;
else if (!strcasecmp(timer, "T313"))
return PRI_TIMER_T313;
else if (!strcasecmp(timer, "T314"))
return PRI_TIMER_T314;
else if (!strcasecmp(timer, "T316"))
return PRI_TIMER_T316;
else if (!strcasecmp(timer, "T317"))
return PRI_TIMER_T317;
else if (!strcasecmp(timer, "T318"))
return PRI_TIMER_T318;
else if (!strcasecmp(timer, "T319"))
return PRI_TIMER_T319;
else if (!strcasecmp(timer, "T320"))
return PRI_TIMER_T320;
else if (!strcasecmp(timer, "T321"))
return PRI_TIMER_T321;
else if (!strcasecmp(timer, "T322"))
return PRI_TIMER_T322;
else
return -1;
}
static int __pri_read(struct pri *pri, void *buf, int buflen)
{
int res = read(pri->fd, buf, buflen);
if (res < 0) {
if (errno != EAGAIN)
pri_error(pri, "Read on %d failed: %s\n", pri->fd, strerror(errno));
return 0;
}
return res;
}
static int __pri_write(struct pri *pri, void *buf, int buflen)
{
int res = write(pri->fd, buf, buflen);
if (res < 0) {
if (errno != EAGAIN)
pri_error(pri, "Write to %d failed: %s\n", pri->fd, strerror(errno));
return 0;
}
return res;
}
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;
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;
/* Start Q.921 layer */
q921_start(p);
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;
#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(-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;
}
/* 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, char *userchars)
{
if (userchars)
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
}
void pri_sr_set_useruser(struct pri_sr *sr, char *userchars)
{
sr->useruserinfo = userchars;
}
int pri_restart(struct pri *pri)
{
/* Restart Q.921 layer */
if (pri) {
q921_reset(pri);
q921_start(pri, pri->localtype == PRI_CPE);
}
return 0;
}
struct pri *pri_new(int fd, int nodetype, int switchtype)
{
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)
{
if (!io_read)
io_read = __pri_read;
if (!io_write)
io_write = __pri_write;
return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata);
}
void *pri_get_userdata(struct pri *pri)
{
return pri ? pri->userdata : NULL;
}
void pri_set_userdata(struct pri *pri, void *userdata)
{
if (pri)
pri->userdata = userdata;
}
void pri_set_nsf(struct pri *pri, int nsf)
{
if (pri)
pri->nsf = nsf;
}
char *pri_event2str(int id)
{
switch(id) {
@@ -80,6 +310,30 @@ char *pri_event2str(int id)
return "Restart channel";
case PRI_EVENT_RING:
return "Ring";
case PRI_EVENT_HANGUP:
return "Hangup";
case PRI_EVENT_RINGING:
return "Ringing";
case PRI_EVENT_ANSWER:
return "Answer";
case PRI_EVENT_HANGUP_ACK:
return "Hangup ACK";
case PRI_EVENT_RESTART_ACK:
return "Restart ACK";
case PRI_EVENT_FACNAME:
return "FacName";
case PRI_EVENT_INFO_RECEIVED:
return "Info Received";
case PRI_EVENT_PROCEEDING:
return "Proceeding";
case PRI_EVENT_SETUP_ACK:
return "Setup ACK";
case PRI_EVENT_HANGUP_REQ:
return "Hangup Req";
case PRI_EVENT_NOTIFY:
return "Notify";
case PRI_EVENT_PROGRESS:
return "Progress";
case PRI_EVENT_CONFIG_ERR:
return "Configuration Error";
default:
@@ -92,12 +346,9 @@ pri_event *pri_check_event(struct pri *pri)
char buf[1024];
int res;
pri_event *e;
res = read(pri->fd, buf, sizeof(buf));
if (res < 0) {
if (errno != EAGAIN)
fprintf(stderr, "Read on %d failed: %s\n", pri->fd, strerror(errno));
res = pri->read_func ? pri->read_func(pri, buf, sizeof(buf)) : 0;
if (!res)
return NULL;
}
/* Receive the q921 packet */
e = q921_receive(pri, (q921_h *)buf, res);
return e;
@@ -134,7 +385,7 @@ pri_event *pri_mkerror(struct pri *pri, char *errstr)
{
/* Return a configuration error */
pri->ev.err.e = PRI_EVENT_CONFIG_ERR;
strncpy(pri->ev.err.err, errstr, sizeof(pri->ev.err.err) - 1);
libpri_copy_string(pri->ev.err.err, errstr, sizeof(pri->ev.err.err));
return &pri->ev;
}
@@ -169,6 +420,27 @@ void pri_set_debug(struct pri *pri, int debug)
if (!pri)
return;
pri->debug = debug;
if (pri->subchannel)
pri_set_debug(pri->subchannel, debug);
}
int pri_get_debug(struct pri *pri)
{
if (!pri)
return -1;
if (pri->subchannel)
return pri_get_debug(pri->subchannel);
return pri->debug;
}
void pri_facility_enable(struct pri *pri)
{
if (!pri)
return;
pri->sendfacility = 1;
if (pri->subchannel)
pri_facility_enable(pri->subchannel);
return;
}
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
@@ -178,6 +450,48 @@ int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
return q931_alerting(pri, call, channel, info);
}
int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_call_proceeding(pri, call, channel, info);
}
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_call_progress(pri, call, channel, info);
}
int pri_information(struct pri *pri, q931_call *call, char digit)
{
if (!pri || !call)
return -1;
return q931_information(pri, call, digit);
}
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_notify(pri, call, channel, info);
}
void pri_destroycall(struct pri *pri, q931_call *call)
{
if (pri && call)
__q931_destroycall(pri, call);
return;
}
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn)
{
if (!pri || !call)
return -1;
return q931_setup_ack(pri, call, channel, nonisdn);
}
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
{
if (!pri || !call)
@@ -185,6 +499,8 @@ int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
return q931_connect(pri, call, channel, nonisdn);
}
#if 0
/* deprecated routines, use pri_hangup */
int pri_release(struct pri *pri, q931_call *call, int cause)
{
if (!pri || !call)
@@ -198,6 +514,42 @@ int pri_disconnect(struct pri *pri, q931_call *call, int cause)
return -1;
return q931_disconnect(pri, call, cause);
}
#endif
int pri_channel_bridge(q931_call *call1, q931_call *call2)
{
if (!call1 || !call2)
return -1;
/* 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 calls are on the same PRI dchannel
* Currently only support calls on the same dchannel
*/
if (call1->pri != call2->pri)
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)
{
if (!pri || !call)
return -1;
if (cause == -1)
/* normal clear cause */
cause = 16;
return q931_hangup(pri, call, cause);
}
int pri_reset(struct pri *pri, int channel)
{
@@ -217,34 +569,285 @@ void pri_dump_event(struct pri *pri, pri_event *e)
{
if (!pri || !e)
return;
printf("Event type: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_message(pri, "Event type: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
switch(e->gen.e) {
case PRI_EVENT_DCHAN_UP:
case PRI_EVENT_DCHAN_DOWN:
break;
case PRI_EVENT_CONFIG_ERR:
printf("Error: %s", e->err.err);
pri_message(pri, "Error: %s", e->err.err);
break;
case PRI_EVENT_RESTART:
printf("Restart on channel %d\n", e->restart.channel);
pri_message(pri, "Restart on channel %d\n", e->restart.channel);
case PRI_EVENT_RING:
printf("Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
printf("Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
printf("Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
pri_message(pri, "Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
pri_message(pri, "Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
pri_message(pri, "Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
break;
case PRI_EVENT_HANGUP:
printf("Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
break;
default:
printf("Don't know how to dump events of type %d\n", e->gen.e);
pri_message(pri, "Don't know how to dump events of type %d\n", e->gen.e);
}
}
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
int nonisdn, char *caller, int callerplan, int callerpres, char *called,
int calledplan,int ulayer1)
static void pri_sr_init(struct pri_sr *req)
{
memset(req, 0, sizeof(struct pri_sr));
}
int pri_sr_set_connection_call_independent(struct pri_sr *req)
{
if (!req)
return -1;
req->justsignalling = 1; /* have to set justsignalling for all those pesky IEs we need to setup */
return 0;
}
/* Don't call any other pri functions on this */
int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called,
int calledplan)
{
struct pri_sr req;
if (!pri || !c)
return -1;
pri_sr_init(&req);
pri_sr_set_connection_call_independent(&req);
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
if (mwi_message_send(pri, c, &req, 1) < 0) {
pri_message(pri, "Unable to send MWI activate message\n");
return -1;
}
/* Do more stuff when we figure out that the CISC stuff works */
return q931_setup(pri, c, &req);
}
int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called,
int calledplan)
{
struct pri_sr req;
if (!pri || !c)
return -1;
pri_sr_init(&req);
pri_sr_set_connection_call_independent(&req);
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
if(mwi_message_send(pri, c, &req, 0) < 0) {
pri_message(pri, "Unable to send MWI deactivate message\n");
return -1;
}
return q931_setup(pri, c, &req);
}
int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
{
if (!pri || !c)
return -1;
return q931_setup(pri, c, transmode, channel, exclusive, nonisdn, caller, callerplan, callerpres, called, calledplan, ulayer1);
return q931_setup(pri, c, req);
}
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 req;
if (!pri || !c)
return -1;
pri_sr_init(&req);
req.transmode = transmode;
req.channel = channel;
req.exclusive = exclusive;
req.nonisdn = nonisdn;
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
req.userl1 = ulayer1;
return q931_setup(pri, c, &req);
}
static void (*__pri_error)(struct pri *pri, char *stuff);
static void (*__pri_message)(struct pri *pri, char *stuff);
void pri_set_message(void (*func)(struct pri *pri, char *stuff))
{
__pri_message = func;
}
void pri_set_error(void (*func)(struct pri *pri, char *stuff))
{
__pri_error = func;
}
void pri_message(struct pri *pri, char *fmt, ...)
{
char tmp[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
if (__pri_message)
__pri_message(pri, tmp);
else
fputs(tmp, stdout);
}
void pri_error(struct pri *pri, char *fmt, ...)
{
char tmp[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
if (__pri_error)
__pri_error(pri, tmp);
else
fputs(tmp, stderr);
}
/* Set overlap mode */
void pri_set_overlapdial(struct pri *pri,int state)
{
pri->overlapdial = state;
}
int pri_fd(struct pri *pri)
{
return pri->fd;
}
char *pri_dump_info_str(struct pri *pri)
{
char buf[4096];
int len = 0;
#ifdef LIBPRI_COUNTERS
struct q921_frame *f;
int q921outstanding = 0;
#endif
if (!pri)
return NULL;
/* Might be nice to format these a little better */
len += sprintf(buf + len, "Switchtype: %s\n", pri_switch2str(pri->switchtype));
len += sprintf(buf + len, "Type: %s\n", pri_node2str(pri->localtype));
#ifdef LIBPRI_COUNTERS
/* Remember that Q921 Counters include Q931 packets (and any retransmissions) */
len += sprintf(buf + len, "Q931 RX: %d\n", pri->q931_rxcount);
len += sprintf(buf + len, "Q931 TX: %d\n", pri->q931_txcount);
len += sprintf(buf + len, "Q921 RX: %d\n", pri->q921_rxcount);
len += sprintf(buf + len, "Q921 TX: %d\n", pri->q921_txcount);
f = pri->txqueue;
while (f) {
q921outstanding++;
f = f->next;
}
len += sprintf(buf + len, "Q921 Outstanding: %d\n", q921outstanding);
#endif
len += sprintf(buf + len, "Window Length: %d/%d\n", pri->windowlen, pri->window);
len += sprintf(buf + len, "Sentrej: %d\n", pri->sentrej);
len += sprintf(buf + len, "SolicitFbit: %d\n", pri->solicitfbit);
len += sprintf(buf + len, "Retrans: %d\n", pri->retrans);
len += sprintf(buf + len, "Busy: %d\n", pri->busy);
len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial);
len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]);
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, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]);
len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]);
return strdup(buf);
}
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode)
{
return q931_call_getcrv(pri, call, callmode);
}
int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode)
{
return q931_call_setcrv(pri, call, crv, callmode);
}
void pri_enslave(struct pri *master, struct pri *slave)
{
if (master && slave)
slave->callpool = &master->localpool;
}
struct pri_sr *pri_sr_new(void)
{
struct pri_sr *req;
req = malloc(sizeof(struct pri_sr));
if (req)
pri_sr_init(req);
return req;
}
void pri_sr_free(struct pri_sr *sr)
{
free(sr);
}
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn)
{
sr->channel = channel;
sr->exclusive = exclusive;
sr->nonisdn = nonisdn;
return 0;
}
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1)
{
sr->transmode = transmode;
sr->userl1 = userl1;
return 0;
}
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int numcomplete)
{
sr->called = called;
sr->calledplan = calledplan;
sr->numcomplete = numcomplete;
return 0;
}
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
{
sr->caller = caller;
sr->callername = callername;
sr->callerplan = callerplan;
sr->callerpres = callerpres;
return 0;
}
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason)
{
sr->redirectingnum = num;
sr->redirectingplan = plan;
sr->redirectingpres = pres;
sr->redirectingreason = reason;
return 0;
}

1330
pri_facility.c Normal file

File diff suppressed because it is too large Load Diff

263
pri_facility.h Normal file
View File

@@ -0,0 +1,263 @@
/*
This file contains all data structures and definitions associated
with facility message usage and the ROSE components included
within those messages.
by Matthew Fredrickson <creslin@digium.com>
Copyright (C) Digium, Inc. 2004-2005
*/
#ifndef _PRI_FACILITY_H
#define _PRI_FACILITY_H
/* Protocol Profile field */
#define Q932_PROTOCOL_ROSE 0x11 /* X.219 & X.229 */
#define Q932_PROTOCOL_CMIP 0x12 /* Q.941 */
#define Q932_PROTOCOL_ACSE 0x13 /* X.217 & X.227 */
#define Q932_PROTOCOL_GAT 0x16
#define Q932_PROTOCOL_EXTENSIONS 0x1F
/* Argument values */
#define ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE 0x80
#define ROSE_NAME_PRESENTATION_RESTRICTED_NULL 0x87
#define ROSE_NAME_NOT_AVAIL 0x84
/* Component types */
#define COMP_TYPE_INTERPRETATION 0x8B
#define COMP_TYPE_NETWORK_PROTOCOL_PROFILE 0x92
#define COMP_TYPE_INVOKE 0xA1
#define COMP_TYPE_RETURN_RESULT 0xA2
#define COMP_TYPE_RETURN_ERROR 0xA3
#define COMP_TYPE_REJECT 0xA4
#define COMP_TYPE_NFE 0xAA
/* Operation ID values */
/* Q.952 ROSE operations (Diverting) */
#define ROSE_DIVERTING_LEG_INFORMATION1 18
#define ROSE_DIVERTING_LEG_INFORMATION2 0x15
#define ROSE_DIVERTING_LEG_INFORMATION3 19
/* Q.956 ROSE operations (Advice Of Charge) */
#define ROSE_AOC_NO_CHARGING_INFO_AVAILABLE 26
#define ROSE_AOC_CHARGING_REQUEST 30
#define ROSE_AOC_AOCS_CURRENCY 31
#define ROSE_AOC_AOCS_SPECIAL_ARR 32
#define ROSE_AOC_AOCD_CURRENCY 33
#define ROSE_AOC_AOCD_CHARGING_UNIT 34
#define ROSE_AOC_AOCE_CURRENCY 35
#define ROSE_AOC_AOCE_CHARGING_UNIT 36
#define ROSE_AOC_IDENTIFICATION_OF_CHARGE 37
/* Q.SIG operations */
#define SS_CNID_CALLINGNAME 0
#define SS_DIVERTING_LEG_INFORMATION2 21
#define SS_MWI_ACTIVATE 80
#define SS_MWI_DEACTIVATE 81
#define SS_MWI_INTERROGATE 82
/* ROSE definitions and data structures */
#define INVOKE_IDENTIFIER 0x02
#define INVOKE_LINKED_IDENTIFIER 0x80
#define INVOKE_NULL_IDENTIFIER __USE_ASN1_NULL
/* ASN.1 Identifier Octet - Data types */
#define ASN1_TYPE_MASK 0x1f
#define ASN1_BOOLEAN 0x01
#define ASN1_INTEGER 0x02
#define ASN1_BITSTRING 0x03
#define ASN1_OCTETSTRING 0x04
#define ASN1_NULL 0x05
#define ASN1_OBJECTIDENTIFIER 0x06
#define ASN1_OBJECTDESCRIPTOR 0x07
#define ASN1_EXTERN 0x08
#define ASN1_REAL 0x09
#define ASN1_ENUMERATED 0x0a
#define ASN1_EMBEDDEDPDV 0x0b
#define ASN1_UTF8STRING 0x0c
#define ASN1_RELATIVEOBJECTID 0x0d
/* 0x0e & 0x0f are reserved for future ASN.1 editions */
#define ASN1_SEQUENCE 0x10
#define ASN1_SET 0x11
#define ASN1_NUMERICSTRING 0x12
#define ASN1_PRINTABLESTRING 0x13
#define ASN1_TELETEXSTRING 0x14
#define ASN1_IA5STRING 0x16
#define ASN1_UTCTIME 0x17
#define ASN1_GENERALIZEDTIME 0x18
/* ASN.1 Identifier Octet - Tags */
#define ASN1_TAG_0 0x00
#define ASN1_TAG_1 0x01
#define ASN1_TAG_2 0x02
#define ASN1_TAG_3 0x03
#define ASN1_TAG_4 0x04
#define ASN1_TAG_5 0x05
#define ASN1_TAG_6 0x06
#define ASN1_TAG_7 0x07
#define ASN1_TAG_8 0x08
#define ASN1_TAG_9 0x09
/* ASN.1 Identifier Octet - Primitive/Constructor Bit */
#define ASN1_PC_MASK 0x20
#define ASN1_PRIMITIVE 0x00
#define ASN1_CONSTRUCTOR 0x20
/* ASN.1 Identifier Octet - Clan Bits */
#define ASN1_CLAN_MASK 0xc0
#define ASN1_UNIVERSAL 0x00
#define ASN1_APPLICATION 0x40
#define ASN1_CONTEXT_SPECIFIC 0x80
#define ASN1_PRIVATE 0xc0
/* ASN.1 Length masks */
#define ASN1_LEN_INDEF 0x80
#define INVOKE_OPERATION_INT __USE_ASN1_INTEGER
#define INVOKE_OBJECT_ID __USE_ASN1_OBJECTIDENTIFIER
/* Q.952 Divert cause */
#define Q952_DIVERT_REASON_UNKNOWN 0x00
#define Q952_DIVERT_REASON_CFU 0x01
#define Q952_DIVERT_REASON_CFB 0x02
#define Q952_DIVERT_REASON_CFNR 0x03
#define Q952_DIVERT_REASON_CD 0x04
#define Q952_DIVERT_REASON_IMMEDIATE 0x05
/* Q.SIG Divert cause. Listed in ECMA-174 */
#define QSIG_DIVERT_REASON_UNKNOWN 0x00 /* Call forward unknown reason */
#define QSIG_DIVERT_REASON_CFU 0x01 /* Call Forward Unconditional (other reason) */
#define QSIG_DIVERT_REASON_CFB 0x02 /* Call Forward Busy */
#define QSIG_DIVERT_REASON_CFNR 0x03 /* Call Forward No Reply */
/* Q.932 Type of number */
#define Q932_TON_UNKNOWN 0x00
#define Q932_TON_INTERNATIONAL 0x01
#define Q932_TON_NATIONAL 0x02
#define Q932_TON_NET_SPECIFIC 0x03
#define Q932_TON_SUBSCRIBER 0x04
#define Q932_TON_ABBREVIATED 0x06
struct rose_component {
u_int8_t type;
u_int8_t len;
u_int8_t data[0];
};
#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("XX Got component %d (0x%02X), length %d\n", (component)->type, (component)->type, (component)->len); \
if ((component)->len > 0) { \
int zzz; \
pri_message("XX Data:"); \
for (zzz = 0; zzz < (component)->len; ++zzz) \
pri_message(" %02X", (component)->data[zzz]); \
pri_message("\n"); \
}
*/
#define NEXT_COMPONENT(component, idx) \
(idx) += (component)->len + 2
#define SUB_COMPONENT(component, idx) \
(idx) += 2
#define CHECK_COMPONENT(component, comptype, message) \
if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
pri_message(pri, (message), (component)->type); \
break; \
}
#define ASN1_GET_INTEGER(component, variable) \
do { \
int comp_idx; \
(variable) = 0; \
for (comp_idx = 0; comp_idx < (component)->len; ++comp_idx) \
(variable) = ((variable) << 8) | (component)->data[comp_idx]; \
} while (0)
#define ASN1_FIXUP_LEN(component, size) \
do { \
if ((component)->len == ASN1_LEN_INDEF) \
size += 2; \
} while (0)
#define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
do { \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
(component)->len = 0; \
(idx) += 2; \
} while (0)
#define ASN1_ADD_BYTECOMP(component, comptype, ptr, idx, value) \
do { \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
(component)->len = 1; \
(component)->data[0] = (value); \
(idx) += 3; \
} while (0)
#define ASN1_ADD_WORDCOMP(component, comptype, ptr, idx, value) \
do { \
int __val = (value); \
int __i = 0; \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
if ((__val >> 24)) \
(component)->data[__i++] = (__val >> 24) & 0xff; \
if ((__val >> 16)) \
(component)->data[__i++] = (__val >> 16) & 0xff; \
if ((__val >> 8)) \
(component)->data[__i++] = (__val >> 8) & 0xff; \
(component)->data[__i++] = __val & 0xff; \
(component)->len = __i; \
(idx) += 2 + __i; \
} while (0)
#define ASN1_PUSH(stack, stackpointer, component) \
(stack)[(stackpointer)++] = (component)
#define ASN1_FIXUP(stack, stackpointer, data, idx) \
do { \
--(stackpointer); \
(stack)[(stackpointer)]->len = (unsigned char *)&((data)[(idx)]) - (unsigned char *)(stack)[(stackpointer)] - 2; \
} while (0)
/* 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);
extern int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
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 */
extern int asn1_name_decode(void * data, int len, char *namebuf, int buflen);
extern int typeofnumber_from_q931(struct pri *pri, int ton);
extern int redirectingreason_from_q931(struct pri *pri, int redirectingreason);
/* Queues an MWI apdu on a the given call */
extern int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
/* starts a 2BCT */
extern int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
/* 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 */
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 */
extern int pri_call_apdu_queue_cleanup(q931_call *call);
/* Adds the "standard" ADPUs to a call */
extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
#endif /* _PRI_FACILITY_H */

171
pri_internal.h Executable file → Normal file
View File

@@ -40,24 +40,38 @@ enum q931_mode;
/* No more than 128 scheduled events */
#define MAX_SCHED 128
#define MAX_TIMERS 32
struct pri {
int fd; /* File descriptor for D-Channel */
pri_io_cb read_func; /* Read data callback */
pri_io_cb write_func; /* Write data callback */
void *userdata;
struct pri *subchannel; /* Sub-channel if appropriate */
struct pri *master; /* Master channel if appropriate */
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */
int debug; /* Debug stuff */
int state; /* State of D-channel */
int switchtype; /* Switch type */
int nsf; /* Network-Specific Facility (if any) */
int localtype; /* Local network type (unknown, network, cpe) */
int remotetype; /* Remote network type (unknown, network, cpe) */
int sapi;
int tei;
int protodisc;
/* Q.921 State */
int q921_state;
int window; /* Max window size */
int windowlen; /* Fullness of window */
int v_s; /* Next N(S) for transmission */
int v_a; /* Last acknowledged frame */
int v_r; /* Next frame expected to be received */
int v_na; /* What we've told our peer we've acknowledged */
int solicitfbit; /* Have we sent an I or S frame with the F-bit set? */
int retrans; /* Retransmissions */
int sentrej; /* Are we in reject state */
int cref; /* Next call reference value */
@@ -67,7 +81,9 @@ struct pri {
int sabme_timer; /* SABME retransmit */
int t203_timer; /* Max idle time */
int t200_timer; /* T-200 retransmission timer */
/* All ISDN Timer values */
int timers[MAX_TIMERS];
/* Used by scheduler */
struct timeval tv;
int schedev;
@@ -77,7 +93,152 @@ struct pri {
struct q921_frame *txqueue;
/* Q.931 calls */
q931_call *calls;
q931_call **callpool;
q931_call *localpool;
/* do we do overlap dialing */
int overlapdial;
#ifdef LIBPRI_COUNTERS
/* q921/q931 packet counters */
unsigned int q921_txcount;
unsigned int q921_rxcount;
unsigned int q931_txcount;
unsigned int q931_rxcount;
#endif
unsigned char last_invoke; /* Last ROSE invoke ID */
unsigned char sendfacility;
};
struct pri_sr {
int transmode;
int channel;
int exclusive;
int nonisdn;
char *caller;
int callerplan;
char *callername;
int callerpres;
char *called;
int calledplan;
int userl1;
int numcomplete;
char *redirectingnum;
int redirectingplan;
int redirectingpres;
int redirectingreason;
int justsignalling;
char *useruserinfo;
};
/* Internal switch types */
#define PRI_SWITCH_GR303_EOC_PATH 19
#define PRI_SWITCH_GR303_TMC_SWITCHING 20
struct apdu_event {
int message; /* What message to send the ADPU in */
void (*callback)(void *data); /* Callback function for when response is received */
void *data; /* Data to callback */
unsigned char apdu[255]; /* ADPU to send */
int apdu_len; /* Length of ADPU */
int sent; /* Have we been sent already? */
struct apdu_event *next; /* Linked list pointer */
};
/* q931_call datastructure */
struct q931_call {
struct pri *pri; /* PRI */
int cr; /* Call Reference */
int forceinvert; /* Force inversion of call number even if 0 */
q931_call *next;
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
int slotmap;
/* An explicit channel (Channel Identifier IE) (-1 means not specified) */
int channelno;
/* An explicit DS1 (-1 means not specified) */
int ds1no;
/* Whether or not the ds1 is explicitly identified or implicit. If implicit
the bchan is on the same span as the current active dchan (NFAS) */
int ds1explicit;
/* Channel flags (0 means none retrieved) */
int chanflags;
int alive; /* Whether or not the call is alive */
int acked; /* Whether setup has been acked or not */
int sendhangupack; /* Whether or not to send a hangup ack */
int proc; /* Whether we've sent a call proceeding / alerting */
int ri; /* Restart Indicator (Restart Indicator IE) */
/* Bearer Capability */
int transcapability;
int transmoderate;
int transmultiple;
int userl1;
int userl2;
int userl3;
int rateadaption;
int sentchannel;
int justsignalling; /* for a signalling-only connection */
int progcode; /* Progress coding */
int progloc; /* Progress Location */
int progress; /* Progress indicator */
int progressmask; /* Progress Indicator bitmask */
int notify; /* Notification */
int causecode; /* Cause Coding */
int causeloc; /* Cause Location */
int cause; /* Cause of clearing */
int peercallstate; /* Call state of peer as reported */
int ourcallstate; /* Our call state */
int sugcallstate; /* Status call state */
int callerplan;
int callerplanani;
int callerpres; /* Caller presentation */
char callerani[256]; /* Caller */
char callernum[256];
char callername[256];
char digitbuf[64]; /* Buffer for digits that come in KEYPAD_FACILITY */
int ani2; /* ANI II */
int calledplan;
int nonisdn;
char callednum[256]; /* Called Number */
int complete; /* no more digits coming */
int newcall; /* if the received message has a new call reference value */
int retranstimer; /* Timer for retransmitting DISC */
int t308_timedout; /* Whether t308 timed out once */
int redirectingplan;
int redirectingpres;
int redirectingreason;
char redirectingnum[256]; /* Number of redirecting party */
char redirectingname[256]; /* Name of redirecting party */
/* Filled in cases of multiple diversions */
int origcalledplan;
int origcalledpres;
int origredirectingreason; /* Original reason for redirect (in cases of multiple redirects) */
char origcalledname[256]; /* Original name of person being called */
char origcallednum[256]; /* Orignal number of person being called */
int useruserprotocoldisc;
char useruserinfo[256];
char callingsubaddr[256]; /* Calling parties sub address */
long aoc_units; /* Advice of Charge Units */
struct apdu_event *apdus; /* APDU queue for call */
};
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
@@ -88,4 +249,10 @@ extern void pri_schedule_del(struct pri *pri, int ev);
extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
extern void pri_message(struct pri *pri, char *fmt, ...);
extern void pri_error(struct pri *pri, char *fmt, ...);
void libpri_copy_string(char *dst, const char *src, size_t size);
#endif

34
pri_q921.h Executable file → Normal file
View File

@@ -26,15 +26,19 @@
#define _PRI_Q921_H
#include <sys/types.h>
#if defined(__linux__)
#include <endian.h>
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __BIG_ENDIAN _BIG_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#endif
/* Timer values */
#define T_WAIT_MIN 2000
#define T_WAIT_MAX 10000
#define T_200 1000 /* 1 second between SABME's */
#define T_203 10000 /* 10 seconds with no packets max */
#define N_200 3 /* 3 retries */
#define Q921_FRAMETYPE_MASK 0x3
@@ -43,8 +47,17 @@
#define Q921_FRAMETYPE_S 0x1
#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_CALLPROC 0
#define Q921_SAPI_CALL_CTRL 0
#define Q921_SAPI_GR303_EOC 1
#define Q921_SAPI_GR303_TMC_SWITCHING 1
#define Q921_SAPI_GR303_TMC_CALLPROC 0
#define Q921_SAPI_CALL_CTRL 0
#define Q921_SAPI_PACKET_MODE 1
#define Q921_SAPI_X25_LAYER3 16
#define Q921_SAPI_LAYER2_MANAGEMENT 63
@@ -65,7 +78,7 @@ typedef struct q921_header {
u_int8_t tei:7; /* Terminal Endpoint Identifier (0) */
#endif
u_int8_t data[0]; /* Further data */
} q921_header;
} __attribute__ ((packed)) q921_header;
/* A Supervisory Format frame */
typedef struct q921_s {
@@ -85,7 +98,7 @@ typedef struct q921_s {
#endif
u_int8_t data[0]; /* Any further data */
u_int8_t fcs[2]; /* At least an FCS */
} q921_s;
} __attribute__ ((packed)) q921_s;
/* An Unnumbered Format frame */
typedef struct q921_u {
@@ -103,7 +116,7 @@ typedef struct q921_u {
#endif
u_int8_t data[0]; /* Any further data */
u_int8_t fcs[2]; /* At least an FCS */
} q921_u;
} __attribute__ ((packed)) q921_u;
/* An Information frame */
typedef struct q921_i {
@@ -134,10 +147,11 @@ typedef union {
typedef struct q921_frame {
struct q921_frame *next; /* Next in list */
int len; /* Length of header + body */
int transmitted; /* Have we been transmitted */
q921_i h;
} q921_frame;
#define Q921_INC(j) (j) = ((j) + 1) % 128
#define Q921_INC(j) (j) = (((j) + 1) % 128)
typedef enum q921_state {
Q921_LINK_CONNECTION_RELEASED, /* Also known as TEI_ASSIGNED */
@@ -147,10 +161,10 @@ typedef enum q921_state {
} q921_state;
/* Dumps a *known good* Q.921 packet */
extern void q921_dump(q921_h *h, int len, int showraw, int txrx);
extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
/* Bring up the D-channel */
extern void q921_start(struct pri *pri);
extern void q921_start(struct pri *pri, int now);
extern void q921_reset(struct pri *pri);

79
pri_q931.h Executable file → Normal file
View File

@@ -81,7 +81,7 @@ typedef struct q931_h {
#endif
u_int8_t contents[0];
u_int8_t crv[3];
} q931_h;
} __attribute__ ((packed)) q931_h;
/* Message type header */
@@ -94,25 +94,20 @@ typedef struct q931_mh {
u_int8_t f:1;
#endif
u_int8_t data[0];
} q931_mh;
} __attribute__ ((packed)) q931_mh;
/* Information element format */
typedef struct q931_ie {
#if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t f:1;
u_int8_t ie:7;
#else
u_int8_t ie:7;
u_int8_t f:1;
#endif
u_int8_t ie;
u_int8_t len;
u_int8_t data[0];
} q931_ie;
} __attribute__ ((packed)) q931_ie;
#define Q931_RES_HAVEEVENT (1 << 0)
#define Q931_RES_INERRROR (1 << 1)
#define Q931_PROTOCOL_DISCRIMINATOR 0x08
#define GR303_PROTOCOL_DISCRIMINATOR 0x4f
/* Q.931 / National ISDN Message Types */
@@ -165,6 +160,7 @@ typedef struct q931_ie {
/* Q.931 / National ISDN Information Elements */
#define Q931_LOCKING_SHIFT 0x90
#define Q931_NON_LOCKING_SHIFT 0x98
#define Q931_BEARER_CAPABILITY 0x04
#define Q931_CAUSE 0x08
#define Q931_CALL_STATE 0x14
@@ -190,14 +186,21 @@ typedef struct q931_ie {
#define Q931_LOW_LAYER_COMPAT 0x7c
#define Q931_HIGH_LAYER_COMPAT 0x7d
#define Q931_CODESET(x) ((x) << 8)
#define Q931_IE_CODESET(x) ((x) >> 8)
#define Q931_IE_IE(x) ((x) & 0xff)
#define Q931_FULL_IE(codeset, ie) (((codeset) << 8) | ((ie) & 0xff))
#define Q931_DISPLAY 0x28
#define Q931_IE_SEGMENTED_MSG 0x00
#define Q931_IE_CHANGE_STATUS 0x01
#define Q931_IE_CONNECTED_NUM 0x0C
#define Q931_IE_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
#define Q931_IE_CONNECTED_ADDR 0x0C
#define Q931_IE_CONNECTED_NUM 0x4C
#define Q931_IE_CALL_IDENTITY 0x10
#define Q931_IE_FACILITY 0x1c
#define Q931_IE_ENDPOINT_ID 0x26
#define Q931_IE_NOTIFY_IND 0x27
#define Q931_IE_DISPLAY 0x28
#define Q931_IE_TIME_DATE 0x29
#define Q931_IE_KEYPAD_FACILITY 0x2c
#define Q931_IE_CALL_STATUS 0x2d
@@ -205,6 +208,7 @@ typedef struct q931_ie {
#define Q931_IE_INFO_REQUEST 0x32
#define Q931_IE_SIGNAL 0x34
#define Q931_IE_SWITCHHOOK 0x36
#define Q931_IE_GENERIC_DIGITS (0x37 | Q931_CODESET(6))
#define Q931_IE_FEATURE_ACTIVATE 0x38
#define Q931_IE_FEATURE_IND 0x39
#define Q931_IE_ORIGINAL_CALLED_NUMBER 0x73
@@ -214,14 +218,44 @@ typedef struct q931_ie {
#define Q931_IE_USER_USER 0x7E
#define Q931_IE_ESCAPE_FOR_EXT 0x7F
/* Call state stuff */
#define Q931_CALL_STATE_NULL 0
#define Q931_CALL_STATE_CALL_INITIATED 1
#define Q931_CALL_STATE_OVERLAP_SENDING 2
#define Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING 3
#define Q931_CALL_STATE_CALL_DELIVERED 4
#define Q931_CALL_STATE_CALL_PRESENT 6
#define Q931_CALL_STATE_CALL_RECEIVED 7
#define Q931_CALL_STATE_CONNECT_REQUEST 8
#define Q931_CALL_STATE_INCOMING_CALL_PROCEEDING 9
#define Q931_CALL_STATE_ACTIVE 10
#define Q931_CALL_STATE_DISCONNECT_REQUEST 11
#define Q931_CALL_STATE_DISCONNECT_INDICATION 12
#define Q931_CALL_STATE_SUSPEND_REQUEST 15
#define Q931_CALL_STATE_RESUME_REQUEST 17
#define Q931_CALL_STATE_RELEASE_REQUEST 19
#define Q931_CALL_STATE_OVERLAP_RECEIVING 25
#define Q931_CALL_STATE_RESTART_REQUEST 61
#define Q931_CALL_STATE_RESTART 62
/* EuroISDN */
#define Q931_SENDING_COMPLETE 0x21
#define Q931_SENDING_COMPLETE 0xa1
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);
extern int q931_call_proceeding(struct pri *pri, q931_call *call);
extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
extern int q931_information(struct pri *pri, q931_call *call, char digit);
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
@@ -229,12 +263,21 @@ extern int q931_release(struct pri *pri, q931_call *call, int cause);
extern int q931_disconnect(struct pri *pri, q931_call *call, int cause);
extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
extern int q931_restart(struct pri *pri, int channel);
extern int q931_facility(struct pri *pri, q931_call *call);
extern int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode);
extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
extern q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
int nonisdn, char *caller, int callerplan, int callerpres, char *called,
int calledplan, int ulay1);
extern void q931_dump(q931_h *h, int len, int txrx);
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);
#endif

89
pri_timers.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001, Linux Support Services, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _PRI_TIMERS_H
#define _PRI_TIMERS_H
/* -1 means we dont currently support the timer/counter */
#define PRI_TIMERS_DEFAULT { 3, /* N200 */ \
-1, /* N201 */ \
-1, /* N202 */ \
7, /* K */ \
1000, /* T200 */ \
-1, /* T201 */ \
-1, /* T202 */ \
10000, /* T203 */ \
-1, /* T300 */ \
-1, /* T301 */ \
-1, /* T302 */ \
-1, /* T303 */ \
-1, /* T304 */ \
30000, /* T305 */ \
-1, /* T306 */ \
-1, /* T307 */ \
4000, /* T308 */ \
-1, /* T309 */ \
-1, /* T310 */ \
4000, /* T313 */ \
-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 */
#define PRI_TIMERS_UNKNOWN PRI_TIMERS_DEFAULT
#define PRI_TIMERS_NI2 PRI_TIMERS_DEFAULT
#define PRI_TIMERS_DMS100 PRI_TIMERS_DEFAULT
#define PRI_TIMERS_LUCENT5E PRI_TIMERS_DEFAULT
#define PRI_TIMERS_ATT4ESS PRI_TIMERS_DEFAULT
#define PRI_TIMERS_EUROISDN_E1 PRI_TIMERS_DEFAULT
#define PRI_TIMERS_EUROISDN_T1 PRI_TIMERS_DEFAULT
#define PRI_TIMERS_NI1 PRI_TIMERS_DEFAULT
#define PRI_TIMERS_GR303_EOC PRI_TIMERS_DEFAULT
#define PRI_TIMERS_GR303_TMC PRI_TIMERS_DEFAULT
#define PRI_TIMERS_QSIG PRI_TIMERS_DEFAULT
#define __PRI_TIMERS_GR303_EOC_INT PRI_TIMERS_DEFAULT
#define __PRI_TIMERS_GR303_TMC_INT PRI_TIMERS_DEFAULT
#define PRI_TIMERS_ALL { PRI_TIMERS_UNKNOWN, \
PRI_TIMERS_NI2, \
PRI_TIMERS_DMS100, \
PRI_TIMERS_LUCENT5E, \
PRI_TIMERS_ATT4ESS, \
PRI_TIMERS_EUROISDN_E1, \
PRI_TIMERS_EUROISDN_T1, \
PRI_TIMERS_NI1, \
PRI_TIMERS_QSIG, \
PRI_TIMERS_GR303_EOC, \
PRI_TIMERS_GR303_TMC, \
__PRI_TIMERS_GR303_EOC_INT, \
__PRI_TIMERS_GR303_TMC_INT, \
}
#endif

32
pridump.c Executable file → Normal file
View File

@@ -1,9 +1,9 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-support.net>
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001, Linux Support Services, Inc.
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -36,7 +36,12 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.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"
@@ -62,12 +67,12 @@ static int pri_open(char *dev)
return dfd;
}
static void dump_packet(char *buf, int len, int txrx)
static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
{
q921_h *h = (q921_h *)buf;
q921_dump(h, len, 1, txrx);
q921_dump(pri, h, len, 1, txrx);
if (!((h->h.data[0] & Q921_FRAMETYPE_MASK) & 0x3)) {
q931_dump((q931_h *)(h->i.data), len - 4, txrx);
q931_dump(pri, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
}
fflush(stdout);
fflush(stderr);
@@ -98,18 +103,28 @@ static int pri_bridge(int d1, int d2)
if (FD_ISSET(d1, &fds)) {
/* Copy from d1 to d2 */
res = read(d1, buf, sizeof(buf));
dump_packet(buf, res, 1);
dump_packet((struct pri *)NULL, buf, res, 1);
res = write(d2, buf, res);
}
if (FD_ISSET(d2, &fds)) {
/* Copy from d2 to d1 */
res = read(d2, buf, sizeof(buf));
dump_packet(buf, res, 0);
dump_packet((struct pri *)NULL, buf, res, 0);
res = write(d1, buf, res);
}
}
}
static void my_pri_message(struct pri *pri, char *stuff)
{
fprintf(stdout, "%s", stuff);
}
static void my_pri_error(struct pri *pri, char *stuff)
{
fprintf(stderr, "%s", stuff);
}
int main(int argc, char *argv[])
{
int d1, d2;
@@ -119,6 +134,9 @@ int main(int argc, char *argv[])
exit(1);
}
pri_set_message(my_pri_message);
pri_set_error(my_pri_error);
d1 = pri_open(argv[1]);
if (d1 < 0)
exit(1);

42
prisched.c Executable file → Normal file
View File

@@ -1,9 +1,9 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-support.net>
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001, Linux Support Services, Inc.
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -22,9 +22,10 @@
*
*/
#include <stdio.h>
#include "libpri.h"
#include "pri_internal.h"
#include <stdio.h>
static int maxsched = 0;
@@ -38,7 +39,7 @@ int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), vo
if (!pri->pri_sched[x].callback)
break;
if (x == MAX_SCHED) {
fprintf(stderr, "No more room in scheduler\n");
pri_error(pri, "No more room in scheduler\n");
return -1;
}
if (x > maxsched)
@@ -60,6 +61,9 @@ struct timeval *pri_schedule_next(struct pri *pri)
{
struct timeval *closest = NULL;
int x;
/* Check subchannels */
if (pri->subchannel)
closest = pri_schedule_next(pri->subchannel);
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
(!closest || (closest->tv_sec > pri->pri_sched[x].when.tv_sec) ||
@@ -70,19 +74,23 @@ struct timeval *pri_schedule_next(struct pri *pri)
return closest;
}
pri_event *pri_schedule_run(struct pri *pri)
static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
{
struct timeval tv;
int x;
void (*callback)(void *);
void *data;
gettimeofday(&tv, NULL);
pri_event *e;
if (pri->subchannel) {
if ((e = __pri_schedule_run(pri->subchannel, tv))) {
return e;
}
}
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
((pri->pri_sched[x].when.tv_sec < tv.tv_sec) ||
((pri->pri_sched[x].when.tv_sec == tv.tv_sec) &&
(pri->pri_sched[x].when.tv_usec <= tv.tv_usec)))) {
pri->schedev = 0;
((pri->pri_sched[x].when.tv_sec < tv->tv_sec) ||
((pri->pri_sched[x].when.tv_sec == tv->tv_sec) &&
(pri->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
pri->schedev = 0;
callback = pri->pri_sched[x].callback;
data = pri->pri_sched[x].data;
pri->pri_sched[x].callback = NULL;
@@ -90,14 +98,22 @@ pri_event *pri_schedule_run(struct pri *pri)
callback(data);
if (pri->schedev)
return &pri->ev;
}
}
}
return NULL;
}
pri_event *pri_schedule_run(struct pri *pri)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return __pri_schedule_run(pri, &tv);
}
void pri_schedule_del(struct pri *pri,int id)
{
if ((id >= MAX_SCHED) || (id < 0))
fprintf(stderr, "Asked to delete sched id %d???\n", id);
pri_error(pri, "Asked to delete sched id %d???\n", id);
pri->pri_sched[id].callback = NULL;
}

69
pritest.c Executable file → Normal file
View File

@@ -1,9 +1,9 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-support.net>
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001, Linux Support Services, Inc.
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -40,7 +40,11 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include "libpri.h"
@@ -48,6 +52,8 @@
#define PRI_DEF_SWITCHTYPE PRI_SWITCH_NI2
#define MAX_CHAN 32
#define DCHANNEL_TIMESLOT 16
static int offset = 0;
@@ -114,6 +120,10 @@ static int str2switch(char *swtype)
return PRI_SWITCH_ATT4ESS;
if (!strcasecmp(swtype, "euroisdn"))
return PRI_SWITCH_EUROISDN_E1;
if (!strcasecmp(swtype, "gr303eoc"))
return PRI_SWITCH_GR303_EOC;
if (!strcasecmp(swtype, "gr303tmc"))
return PRI_SWITCH_GR303_TMC;
return -1;
}
@@ -162,10 +172,50 @@ static void launch_channel(int channo)
}
static int get_free_channel(int channo)
{
channo--;
if((channo>MAX_CHAN)||(channo<0)) {
fprintf(stderr, "Invalid Bchannel RANGE <%d", channo);
return 0;
};
while(chans[channo].pid) {
channo--;
}
return channo;
}
/* place here criteria for completion of destination number */
static int number_incommplete(char *number)
{
return strlen(number) < 3;
}
static void start_channel(struct pri *pri, pri_event *e)
{
int channo = e->ring.channel;
int flag = 1;
pri_event_ring *ring = &e->ring;
if(channo == -1) {
channo = e->ring.channel = get_free_channel(MAX_CHAN);
if(channo == DCHANNEL_TIMESLOT)
channo = e->ring.channel = get_free_channel(MAX_CHAN);
fprintf(stdout, "Any channel selected: %d\n", channo);
if(!channo) {
pri_release(pri, ring->call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
fprintf(stdout, "Abort call due to no avl B channels\n");
return;
}
flag = 0;
}
/* Make sure it's a valid number */
if ((channo >= MAX_CHAN) || (channo < 0)) {
fprintf(stderr, "--!! Channel %d is out of range\n", channo);
@@ -185,7 +235,11 @@ static void start_channel(struct pri *pri, pri_event *e)
chans[channo].call = e->ring.call;
/* Answer the line */
pri_answer(pri, chans[channo].call, channo, 1);
if(flag) {
pri_answer(pri, chans[channo].call, channo, 1);
} else {
pri_need_more_info(pri, chans[channo].call, channo, 1);
}
/* Launch a process to handle it */
launch_channel(channo);
@@ -222,6 +276,14 @@ static void handle_pri_event(struct pri *pri, pri_event *e)
break;
case PRI_EVENT_HANGUP_ACK:
/* Ignore */
break;
case PRI_EVENT_INFO_RECEIVED:
fprintf(stdout, "number is: %s\n", e->ring.callednum);
if(!number_incommplete(e->ring.callednum)) {
fprintf(stdout, "final number is: %s\n", e->ring.callednum);
pri_answer(pri, e->ring.call, 0, 1);
}
break;
default:
fprintf(stderr, "--!! Unknown PRI event %d\n", e->e);
@@ -241,6 +303,7 @@ static int run_pri(int dfd, int swtype, int node)
fprintf(stderr, "Unable to create PRI\n");
return -1;
}
pri_set_debug(pri, -1);
for (;;) {
/* Run the D-Channel */

475
q921.c Executable file → Normal file
View File

@@ -1,9 +1,9 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@linux-support.net>
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001, Linux Support Services, Inc.
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -21,12 +21,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
#include "pri_q921.h"
@@ -41,13 +42,16 @@
#define RANDOM_DROPS
*/
#define Q921_INIT(hf) do { \
(hf).h.sapi = 0; \
#define Q921_INIT(pri, hf) do { \
memset(&(hf),0,sizeof(hf)); \
(hf).h.sapi = (pri)->sapi; \
(hf).h.ea1 = 0; \
(hf).h.ea2 = 1; \
(hf).h.tei = 0; \
(hf).h.tei = (pri)->tei; \
} while(0)
static void reschedule_t203(struct pri *pri);
static void q921_discard_retransmissions(struct pri *pri)
{
struct q921_frame *f, *p;
@@ -61,31 +65,37 @@ static void q921_discard_retransmissions(struct pri *pri)
pri->txqueue = NULL;
}
static int q921_transmit(struct pri *pri, q921_h *h, int len) {
static int q921_transmit(struct pri *pri, q921_h *h, int len)
{
int res;
if (pri->master)
return q921_transmit(pri->master, h, len);
#ifdef RANDOM_DROPS
if (!(random() % 3)) {
printf(" === Dropping Packet ===\n");
pri_message(pri, " === Dropping Packet ===\n");
return 0;
}
#endif
#ifdef LIBPRI_COUNTERS
pri->q921_txcount++;
#endif
/* Just send it raw */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
/* Write an extra two bytes for the FCS */
res = write(pri->fd, h, len + 2);
res = pri->write_func ? pri->write_func(pri, h, len + 2) : 0;
if (res != (len + 2)) {
fprintf(stderr, "Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
pri_error(pri, "Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
return -1;
}
reschedule_t203(pri);
return 0;
}
static void q921_send_ua(struct pri *pri, int pfbit)
{
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.u.m3 = 3; /* M3 = 3 */
h.u.m2 = 0; /* M2 = 0 */
h.u.p_f = pfbit; /* Final bit on */
@@ -98,22 +108,26 @@ static void q921_send_ua(struct pri *pri, int pfbit)
h.h.c_r = 1;
break;
default:
fprintf(stderr, "Don't know how to U/A on a type %d node\n", pri->localtype);
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)
printf("Sending Unnumbered Acknowledgement\n");
pri_message(pri, "Sending Unnumbered Acknowledgement\n");
q921_transmit(pri, &h, 3);
}
static void q921_send_sabme(void *vpri)
static void q921_send_sabme_now(void *vpri);
static void q921_send_sabme(void *vpri, int now)
{
struct pri *pri = vpri;
q921_h h;
pri_schedule_del(pri, pri->sabme_timer);
pri->sabme_timer = 0;
pri->sabme_timer = pri_schedule_event(pri, T_200, q921_send_sabme, pri);
Q921_INIT(h);
pri->sabme_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], q921_send_sabme_now, pri);
if (!now)
return;
Q921_INIT(pri, h);
h.u.m3 = 3; /* M3 = 3 */
h.u.m2 = 3; /* M2 = 3 */
h.u.p_f = 1; /* Poll bit set */
@@ -126,31 +140,59 @@ static void q921_send_sabme(void *vpri)
h.h.c_r = 0;
break;
default:
fprintf(stderr, "Don't know how to U/A on a type %d node\n", pri->localtype);
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)
printf("Sending Set Asynchronous Balanced Mode Extended\n");
pri_message(pri, "Sending Set Asynchronous Balanced Mode Extended\n");
q921_transmit(pri, &h, 3);
pri->q921_state = Q921_AWAITING_ESTABLISH;
}
static void q921_send_sabme_now(void *vpri)
{
q921_send_sabme(vpri, 1);
}
static int q921_ack_packet(struct pri *pri, int num)
{
struct q921_frame *f, *prev = NULL;
f = pri->txqueue;
while(f) {
if (f->h.n_s == num) {
/* Cancel each packet as necessary */
/* That's our packet */
if (prev)
prev->next = f->next;
else
pri->txqueue = f->next;
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;
free(f);
/* Reset retransmission counter if we actually acked something */
pri->retrans = 0;
/* Decrement window size */
pri->windowlen--;
/* Search for something to send */
f = pri->txqueue;
while(f) {
if (!f->transmitted) {
/* Send it now... */
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++;
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
break;
}
f = f->next;
}
return 1;
}
prev = f;
f = f->next;
}
return 0;
@@ -158,57 +200,76 @@ static int q921_ack_packet(struct pri *pri, int num)
static void t203_expire(void *);
static void t200_expire(void *);
static pri_event *q921_dchannel_down(struct pri *pri);
static void q921_ack_rx(struct pri *pri, int ack)
static void reschedule_t203(struct pri *pri)
{
if (pri->t203_timer) {
pri_schedule_del(pri, pri->t203_timer);
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);
}
}
static pri_event *q921_ack_rx(struct pri *pri, int ack)
{
int x;
int cnt=0;
pri_event *ev;
/* Make sure the ACK was within our window */
for (x=pri->v_a; (x != pri->v_s) && (x != ack); Q921_INC(x));
if (x != ack) {
/* ACK was outside of our window --- ignore */
fprintf(stderr, "ACK received outside of window, ignoring\n");
return;
pri_error(pri, "ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a, pri->v_s);
ev = q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
return ev;
}
/* Cancel each packet as necessary */
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_STATE)
printf("-- Since there was nothing left, stopping T200 counter\n");
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_STATE)
printf("-- Stopping T203 counter since we got an ACK\n");
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_STATE)
printf("-- Something left to transmit, restarting T200 counter\n");
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, T_200, t200_expire, pri);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Nothing left, starting T203 counter\n");
pri_message(pri, "-- Nothing left, starting T203 counter\n");
/* Nothing to transmit, start the T203 counter instead */
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
return NULL;
}
static void q921_reject(struct pri *pri)
static void q921_reject(struct pri *pri, int pf)
{
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.s.x0 = 0; /* Always 0 */
h.s.ss = 2; /* Reject */
h.s.ft = 1; /* Frametype (01) */
h.s.n_r = pri->v_r; /* Where to start retransmission */
h.s.p_f = 1; /* XXX Should it always be set to 1? XXX */
h.s.p_f = pf;
switch(pri->localtype) {
case PRI_NETWORK:
h.h.c_r = 0;
@@ -217,17 +278,18 @@ static void q921_reject(struct pri *pri)
h.h.c_r = 1;
break;
default:
fprintf(stderr, "Don't know how to U/A on a type %d node\n", pri->localtype);
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)
printf("Sending Reject (%d)\n", pri->v_r);
pri_message(pri, "Sending Reject (%d)\n", pri->v_r);
pri->sentrej = 1;
q921_transmit(pri, &h, 4);
}
static void q921_rr(struct pri *pri, int pbit) {
static void q921_rr(struct pri *pri, int pbit, int cmd) {
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.s.x0 = 0; /* Always 0 */
h.s.ss = 0; /* Receive Ready */
h.s.ft = 1; /* Frametype (01) */
@@ -235,30 +297,34 @@ static void q921_rr(struct pri *pri, int pbit) {
h.s.p_f = pbit; /* Poll/Final set appropriately */
switch(pri->localtype) {
case PRI_NETWORK:
h.h.c_r = 0;
if (cmd)
h.h.c_r = 1;
else
h.h.c_r = 0;
break;
case PRI_CPE:
h.h.c_r = 1;
if (cmd)
h.h.c_r = 0;
else
h.h.c_r = 1;
break;
default:
fprintf(stderr, "Don't know how to U/A on a type %d node\n", pri->localtype);
pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
return;
}
pri->v_na = pri->v_r; /* Make a note that we've already acked this */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("Sending Receiver Ready (%d)\n", pri->v_r);
pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r);
q921_transmit(pri, &h, 4);
}
static pri_event *q921_dchannel_down(struct pri *pri);
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_STATE)
printf("-- T200 counter expired, What to do...\n");
pri_message(pri, "-- T200 counter expired, What to do...\n");
/* Force Poll bit */
pri->txqueue->h.p_f = 1;
/* Update nr */
@@ -267,26 +333,49 @@ static void t200_expire(void *vpri)
pri->solicitfbit = 1;
pri->retrans++;
/* Up to three retransmissions */
if (pri->retrans < N_200) {
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
/* Reschedule t200_timer */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Retransmitting %d bytes\n", pri->txqueue->len);
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
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)
printf("-- Rescheduling retransmission (%d)\n", pri->retrans);
pri->t200_timer = pri_schedule_event(pri, T_200, t200_expire, pri);
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)
printf("-- Timeout occured, restarting PRI\n");
pri->state = Q921_LINK_CONNECTION_RELEASED;
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);
q921_start(pri, 1);
pri->schedev = 1;
}
} else if (pri->solicitfbit) {
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)
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 {
fprintf(stderr, "T200 counter expired, nothing to send...\n");
pri->t200_timer = 0;
pri_error(pri, "T200 counter expired, nothing to send...\n");
pri->t200_timer = 0;
}
}
@@ -296,7 +385,8 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
for (f=pri->txqueue; f; f = f->next) prev = f;
f = malloc(sizeof(q921_frame) + len + 2);
if (f) {
Q921_INIT(f->h);
memset(f,0,sizeof(q921_frame) + len + 2);
Q921_INIT(pri, f->h);
switch(pri->localtype) {
case PRI_NETWORK:
if (cr)
@@ -312,6 +402,7 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
break;
}
f->next = NULL;
f->transmitted = 0;
f->len = len + 4;
memcpy(f->h.data, buf, len);
f->h.n_s = pri->v_s;
@@ -324,25 +415,35 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
prev->next = f;
else
pri->txqueue = f;
/* Immediately transmit unless we're in a recovery state */
if (!pri->retrans)
q921_transmit(pri, (q921_h *)(&f->h), f->len);
/* Immediately transmit unless we're in a recovery state, or the window
size is too big */
if (!pri->retrans && !pri->busy) {
if (pri->windowlen < pri->window) {
pri->windowlen++;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
f->transmitted++;
} else {
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_STATE)
printf("Stopping T_203 timer\n");
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_STATE)
printf("Starting T_200 timer\n");
pri->t200_timer = pri_schedule_event(pri, T_200, t200_expire, pri);
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_STATE)
printf("T_200 timer already going (%d)\n", pri->t200_timer);
pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
} else {
fprintf(stderr, "!! Out of memory for Q.921 transmit\n");
pri_error(pri, "!! Out of memory for Q.921 transmit\n");
return -1;
}
return 0;
@@ -351,52 +452,63 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
static void t203_expire(void *vpri)
{
struct pri *pri = vpri;
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("T203 counter expired, sending RR and scheduling T203 again\n");
/* Solicit an F-bit in the other's RR */
pri->solicitfbit = 1;
q921_rr(pri, 1);
/* Restart ourselves */
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
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;
pri->retrans = 0;
q921_rr(pri, 1, 1);
/* 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_STATE)
pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
pri->t203_timer = 0;
}
}
static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len)
{
int res;
pri_event *ev;
/* Make sure this is a valid packet */
if (i->n_s == pri->v_r) {
/* Increment next expected I-frame */
Q921_INC(pri->v_r);
/* Handle their ACK */
q921_ack_rx(pri, i->n_r);
pri->sentrej = 0;
ev = q921_ack_rx(pri, i->n_r);
if (ev)
return ev;
if (i->p_f) {
/* If the Poll/Final bit is set, immediate send the RR */
q921_rr(pri, 1);
q921_rr(pri, 1, 0);
} else if (pri->busy) {
q921_rr(pri, 0, 0);
}
/* Receive Q.931 data */
res = q931_receive(pri, (q931_h *)i->data, len - 4);
/* Send an RR if one wasn't sent already */
if (pri->v_na != pri->v_r)
q921_rr(pri, 0);
q921_rr(pri, 0, 0);
if (res == -1) {
return NULL;
}
if (res & Q931_RES_HAVEEVENT)
return &pri->ev;
} else {
if (((pri->v_r - i->n_s) & 127) < pri->window) {
/* It's within our window -- send back an RR */
q921_rr(pri, 0);
} else
q921_reject(pri);
#if 0
q931_reject(pri);
#endif
/* If we haven't already sent a reject, send it now, otherwise
we are obliged to RR */
if (!pri->sentrej)
q921_reject(pri, i->p_f);
else if (i->p_f)
q921_rr(pri, 1, 0);
}
return NULL;
}
void q921_dump(q921_h *h, int len, int showraw, int txrx)
void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx)
{
int x;
char *type;
@@ -404,26 +516,30 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
direction_tag = txrx ? '>' : '<';
if (showraw) {
printf("\n%c [", direction_tag);
for (x=0;x<len;x++)
printf("%02x ",h->raw[x]);
printf("]");
char *buf = malloc(len * 3 + 1);
int buflen = 0;
if (buf) {
for (x=0;x<len;x++)
buflen += sprintf(buf + buflen, "%02x ", h->raw[x]);
pri_message(pri, "\n%c [ %s]\n", direction_tag, buf);
free(buf);
}
}
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
case 0:
case 2:
printf("\n%c Informational frame:\n", direction_tag);
pri_message(pri, "\n%c Informational frame:\n", direction_tag);
break;
case 1:
printf("\n%c Supervisory frame:\n", direction_tag);
pri_message(pri, "\n%c Supervisory frame:\n", direction_tag);
break;
case 3:
printf("\n%c Unnumbered frame:\n", direction_tag);
pri_message(pri, "\n%c Unnumbered frame:\n", direction_tag);
break;
}
printf(
pri_message(pri,
"%c SAPI: %02d C/R: %d EA: %d\n"
"%c TEI: %03d EA: %d\n",
direction_tag,
@@ -437,7 +553,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
case 0:
case 2:
/* Informational frame */
printf(
pri_message(pri,
"%c N(S): %03d 0: %d\n"
"%c N(R): %03d P: %d\n"
"%c %d bytes of data\n",
@@ -464,7 +580,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
type = "REJ (reject)";
break;
}
printf(
pri_message(pri,
"%c Zero: %d S: %d 01: %d [ %s ]\n"
"%c N(R): %03d P/F: %d\n"
"%c %d bytes of data\n",
@@ -510,7 +626,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
break;
}
}
printf(
pri_message(pri,
"%c M3: %d P/F: %d M2: %d 11: %d [ %s ]\n"
"%c %d bytes of data\n",
direction_tag,
@@ -534,11 +650,14 @@ static pri_event *q921_dchannel_up(struct pri *pri)
pri_schedule_del(pri, pri->sabme_timer);
pri->sabme_timer = 0;
/* Reset any rejects */
pri->sentrej = 0;
/* Go into connection established state */
pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;
/* Start the T203 timer */
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
/* Report event that D-Channel is now up */
pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
@@ -562,7 +681,8 @@ void q921_reset(struct pri *pri)
pri->v_a = 0;
pri->v_r = 0;
pri->v_na = 0;
pri->window = 7;
pri->window = pri->timers[PRI_TIMER_K];
pri->windowlen = 0;
pri_schedule_del(pri, pri->sabme_timer);
pri_schedule_del(pri, pri->t203_timer);
pri_schedule_del(pri, pri->t200_timer);
@@ -573,52 +693,39 @@ void q921_reset(struct pri *pri)
pri->solicitfbit = 0;
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->retrans = 0;
pri->sentrej = 0;
/* Discard anything waiting to go out */
q921_discard_retransmissions(pri);
}
pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
{
q921_frame *f;
/* Discard FCS */
len -= 2;
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(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;
/* Check for broadcasts - not yet handled */
if (h->h.tei == Q921_TEI_GROUP)
return NULL;
/* Check for SAPIs we don't yet handle */
if (h->h.sapi != Q921_SAPI_CALL_CTRL)
return NULL;
pri_event *ev;
int sendnow;
switch(h->h.data[0] & Q921_FRAMETYPE_MASK) {
case 0:
case 2:
if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {
fprintf(stderr, "!! Got I-frame while link state %d\n", pri->q921_state);
pri_error(pri, "!! Got I-frame while link state %d\n", pri->q921_state);
return NULL;
}
/* Informational frame */
if (len < 4) {
fprintf(stderr, "!! Received short I-frame\n");
pri_error(pri, "!! Received short I-frame (expected 4, got %d)\n", len);
break;
}
return q921_handle_iframe(pri, &h->i, len);
break;
case 1:
if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {
fprintf(stderr, "!! Got S-frame while link down\n");
pri_error(pri, "!! Got S-frame while link down\n");
return NULL;
}
if (len < 4) {
fprintf(stderr, "!! Received short S-frame\n");
pri_error(pri, "!! Received short S-frame (expected 4, got %d)\n", len);
break;
}
switch(h->s.ss) {
@@ -626,54 +733,61 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
/* Receiver Ready */
pri->busy = 0;
/* Acknowledge frames as necessary */
q921_ack_rx(pri, h->s.n_r);
ev = q921_ack_rx(pri, h->s.n_r);
if (ev)
return ev;
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_STATE)
printf("-- Got RR response to our frame\n");
pri_message(pri, "-- Got RR response to our frame\n");
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Unsolicited RR with P/F bit, responding\n");
q921_rr(pri, 1);
pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
q921_rr(pri, 1, 0);
}
pri->solicitfbit = 0;
}
break;
#if 0
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Got receiver not ready\n");
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;
#endif
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Got reject requesting packet %d... Retransmitting.\n", h->s.n_r);
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);
q921_rr(pri, 1, 0);
}
sendnow = 0;
/* Resend the proper I-frame */
for(f=pri->txqueue;f;f=f->next) {
if (f->h.n_s == h->s.n_r) {
/* Matches the request */
break;
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 (f) {
/* Retransmit the requested frame */
q921_transmit(pri, (q921_h *)(&f->h), f->len);
} else {
if (!sendnow) {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
fprintf(stderr, "!! Got reject for frame %d, but we only have others!\n", 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 */
@@ -684,51 +798,59 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
/* Reset and restart t203 timer */
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
}
break;
default:
fprintf(stderr, "!! 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_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);
}
break;
case 3:
if (len < 3) {
fprintf(stderr, "!! Received short unnumbered frame\n");
pri_error(pri, "!! Received short unnumbered frame\n");
break;
}
switch(h->u.m3) {
case 0:
if (h->u.m2 == 3) {
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)
printf("-- Got Unconnected Mode from peer.\n");
/* Disconnected mode */
if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
return q921_dchannel_down(pri);
pri_message(pri, "-- Got DM Mode from peer.\n");
/* Disconnected mode, try again after T200 */
ev = q921_dchannel_down(pri);
q921_start(pri, 0);
return ev;
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- DM requesting SABME, starting.\n");
pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
#if 0
/* Requesting that we start */
q921_start(pri);
q921_start(pri, 0);
#endif
}
break;
} else if (!h->u.m2) {
printf("XXX Unnumbered Information not implemented XXX\n");
pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
}
break;
case 2:
if (pri->debug & PRI_DEBUG_Q921_STATE)
printf("-- Got Disconnect from peer.\n");
pri_message(pri, "-- Got Disconnect from peer.\n");
/* Acknowledge */
q921_send_ua(pri, h->u.p_f);
return q921_dchannel_down(pri);
ev = q921_dchannel_down(pri);
q921_start(pri, 0);
return ev;
case 3:
if (h->u.m2 == 3) {
/* SABME */
if (pri->debug & PRI_DEBUG_Q921_STATE) {
printf("-- Got SABME from %s peer.\n", h->h.c_r ? "network" : "cpe");
pri_message(pri, "-- Got SABME from %s peer.\n", h->h.c_r ? "network" : "cpe");
}
if (h->h.c_r) {
pri->remotetype = PRI_NETWORK;
@@ -750,22 +872,22 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
/* It's a UA */
if (pri->q921_state == Q921_AWAITING_ESTABLISH) {
if (pri->debug & PRI_DEBUG_Q921_STATE) {
printf("-- Got UA from %s peer Link up.\n", h->h.c_r ? "cpe" : "network");
pri_message(pri, "-- Got UA from %s peer Link up.\n", h->h.c_r ? "cpe" : "network");
}
return q921_dchannel_up(pri);
} else
fprintf(stderr, "!! Got a UA, but i'm in state %d\n", pri->q921_state);
pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state);
} else
fprintf(stderr, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
break;
case 4:
fprintf(stderr, "!! Frame got rejected!\n");
pri_error(pri, "!! Frame got rejected!\n");
break;
case 5:
fprintf(stderr, "!! XID frames not supported\n");
pri_error(pri, "!! XID frames not supported\n");
break;
default:
fprintf(stderr, "!! Don't know what to do with M3=%d u-frames\n", h->u.m3);
pri_error(pri, "!! Don't know what to do with M3=%d u-frames\n", h->u.m3);
}
break;
@@ -773,14 +895,57 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
return NULL;
}
void q921_start(struct pri *pri)
static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
{
pri_event *ev;
/* Discard FCS */
len -= 2;
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;
/* Check for broadcasts - not yet handled */
if (h->h.tei == Q921_TEI_GROUP)
return NULL;
/* 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
#endif
return NULL;
}
ev = __q921_receive_qualified(pri, h, len);
reschedule_t203(pri);
return ev;
}
pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
{
pri_event *e;
e = __q921_receive(pri, h, len);
#ifdef LIBPRI_COUNTERS
pri->q921_rxcount++;
#endif
return e;
}
void q921_start(struct pri *pri, int now)
{
if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
fprintf(stderr, "!! q921_start: Not in 'Link Connection Released' state\n");
pri_error(pri, "!! q921_start: Not in 'Link Connection Released' state\n");
return;
}
/* Reset our interface */
q921_reset(pri);
/* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
q921_send_sabme(pri);
q921_send_sabme(pri, now);
}

2772
q931.c Executable file → Normal file

File diff suppressed because it is too large Load Diff

284
testprilib.c Normal file
View File

@@ -0,0 +1,284 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* This program tests libpri call reception using a zaptel interface.
* Its state machines are setup for RECEIVING CALLS ONLY, so if you
* are trying to both place and receive calls you have to a bit more.
*/
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__) || defined(SOLARIS)
#include <zaptel.h>
#endif
#ifndef SOLARIS
#include <zap.h>
#endif
#include <pthread.h>
#include <sys/select.h>
#include "libpri.h"
#include "pri_q931.h"
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#define DEBUG_LEVEL PRI_DEBUG_ALL
#define PRI_DEF_NODETYPE PRI_CPE
#define PRI_DEF_SWITCHTYPE PRI_SWITCH_NI2
static struct pri *first, *cur;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define TEST_CALLS 32
static void event1(struct pri *pri, pri_event *e)
{
/* Network */
int x;
static q931_call *calls[TEST_CALLS];
char name[256], num[256], dest[256];
switch(e->gen.e) {
case PRI_EVENT_DCHAN_UP:
printf("Network is up. Sending blast of calls!\n");
for (x=0;x<TEST_CALLS;x++) {
sprintf(name, "Caller %d", x + 1);
sprintf(num, "25642860%02d", x+1);
sprintf(dest, "60%02d", x + 1);
if (!(calls[x] = pri_new_call(pri))) {
perror("pri_new_call");
continue;
}
#if 0
{
struct pri_sr *sr;
sr = pri_sr_new();
pri_sr_set_channel(sr, x+1, 0, 0);
pri_sr_set_bearer(sr, 0, PRI_LAYER_1_ULAW);
pri_sr_set_called(sr, dest, PRI_NATIONAL_ISDN, 1);
pri_sr_set_caller(sr, num, name, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
pri_sr_set_redirecting(sr, num, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
if (pri_setup(pri, calls[x], sr))
perror("pri_setup");
pri_sr_free(sr);
}
#else
if (pri_call(pri, calls[x], PRI_TRANS_CAP_DIGITAL, x + 1, 1, 1, num,
PRI_NATIONAL_ISDN, name, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
dest, PRI_NATIONAL_ISDN, PRI_LAYER_1_ULAW)) {
perror("pri_call");
}
#endif
}
printf("Setup %d calls!\n", TEST_CALLS);
break;
case PRI_EVENT_RINGING:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
q931_facility(pri, e->ringing.call);
pri_answer(pri, e->ringing.call, e->ringing.channel, 0);
break;
case PRI_EVENT_HANGUP_REQ:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->hangup.call, e->hangup.cause);
break;
default:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
}
}
static void event2(struct pri *pri, pri_event *e)
{
/* CPE */
switch(e->gen.e) {
case PRI_EVENT_RING:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_proceeding(pri, e->ring.call, e->ring.channel, 0);
pri_acknowledge(pri, e->ring.call, e->ring.channel, 0);
break;
case PRI_EVENT_ANSWER:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->answer.call, PRI_CAUSE_NORMAL_UNSPECIFIED);
break;
case PRI_EVENT_HANGUP:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->hangup.call, e->hangup.cause);
break;
case PRI_EVENT_DCHAN_UP:
default:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
}
}
static void testmsg(char *s)
{
char *c;
static int keeplast = 0;
do {
c = strchr(s, '\n');
if (c) {
*c = '\0';
c++;
}
if (keeplast)
printf("%s", s);
else if (cur == first)
printf("-1 %s", s);
else
printf("-2 %s", s);
if (c)
printf("\n");
s = c;
} while(c && *c);
if (!c)
keeplast = 1;
else
keeplast = 0;
}
static void testerr(char *s)
{
char *c;
static int keeplast = 0;
do {
c = strchr(s, '\n');
if (c) {
*c = '\0';
c++;
}
if (keeplast)
printf("%s", s);
else if (cur == first)
printf("=1 %s", s);
else
printf("=2 %s", s);
if (c)
printf("\n");
s = c;
} while(c && *c);
if (!c)
keeplast = 1;
else
keeplast = 0;
}
static void *dchan(void *data)
{
/* Joint D-channel */
struct pri *pri = data;
struct timeval *next, tv;
pri_event *e;
fd_set fds;
int res;
for(;;) {
if ((next = pri_schedule_next(pri))) {
gettimeofday(&tv, NULL);
tv.tv_sec = next->tv_sec - tv.tv_sec;
tv.tv_usec = next->tv_usec - tv.tv_usec;
if (tv.tv_usec < 0) {
tv.tv_usec += 1000000;
tv.tv_sec -= 1;
}
if (tv.tv_sec < 0) {
tv.tv_sec = 0;
tv.tv_usec = 0;
}
}
FD_ZERO(&fds);
FD_SET(pri_fd(pri), &fds);
res = select(pri_fd(pri) + 1, &fds, NULL, NULL, next ? &tv : NULL);
pthread_mutex_lock(&lock);
cur = pri;
if (res < 0) {
perror("select");
} else if (!res) {
e = pri_schedule_run(pri);
} else {
e = pri_check_event(pri);
}
if (e) {
if (first == pri) {
event1(pri, e);
} else {
event2(pri, e);
}
}
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(int argc, char *argv[])
{
int pair[2];
pthread_t tmp;
struct pri *pri;
pri_set_message(testmsg);
pri_set_error(testerr);
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, pair)) {
perror("socketpair");
exit(1);
}
if (!(pri = pri_new(pair[0], PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
perror("pri(0)");
exit(1);
}
first = pri;
pri_set_debug(pri, DEBUG_LEVEL);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(0)");
exit(1);
}
if (!(pri = pri_new(pair[1], PRI_CPE, PRI_DEF_SWITCHTYPE))) {
perror("pri(1)");
exit(1);
}
pri_set_debug(pri, DEBUG_LEVEL);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(1)");
exit(1);
}
/* Wait for things to run */
sleep(5);
exit(0);
}