Compare commits

..

99 Commits
1.0.6 ... 1.2.1

Author SHA1 Message Date
Kevin P. Fleming
cbf719fa3a make tag in preparation for release
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.2.1@282 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-12-06 23:38:12 +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
21 changed files with 3674 additions and 630 deletions

View File

@@ -1,24 +1,15 @@
libpri 1.0.6
-- Dependencies from .depend were valid from static libary only, not dynamic. 'mkdep'
has been fixed to support the dynamic library version.
libpri 1.0.4
-- Makefile fix for SELinux
libpri 1.0.3
-- Fix Endian to compile for FreeBSD
...
libpri 0.3.0
-- Fix talking to switch
-- Add pri dump
-- Add test application
-- Fix strncpy stuff
-- 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
-- Added PRI_EVENT_HANGUP_ACK so you can know when the disconnect was
acknowledged
libpri 0.1.1
-- Added PRI_DEBUG_Q931_ANOMALY flag so that certain non-error-related
messages would not be output unless specifically desired.
-- Added PRI_DEBUG_Q931_ANOMALY flag so that certain non-error-related
messages would not be output unless specifically desired.
libpri 0.1.0
-- Initial release

View File

@@ -27,17 +27,22 @@
# 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)
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
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_PREFIX?=
INSTALL_BASE=/usr
SOFLAGS = -Wl,-hlibpri.so.1
LDCONFIG = /sbin/ldconfig
ifeq (${OSARCH},Linux)
LDCONFIG_FLAGS=-n
else
@@ -46,6 +51,13 @@ 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
#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.
@@ -58,25 +70,40 @@ endif
all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
update:
@echo "Updating from CVS"
@cvs update -d
@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 $(INSTALL_PREFIX)/usr/lib
mkdir -p $(INSTALL_PREFIX)/usr/include
install -m 644 libpri.h $(INSTALL_PREFIX)/usr/include
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)/usr/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)/usr/lib ; ln -sf libpri.so.1 libpri.so )
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)/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 libpri.so )
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 libpri.so ; $(SOSLINK) )
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 644 $(STATIC_LIBRARY)
endif
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.so.1.0
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.so
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.a
rm -f $(INSTALL_PREFIX)/usr/include/libpri.h
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 $(CFLAGS)
@@ -88,9 +115,11 @@ testprilib: testprilib.o
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
pridump: pridump.o
$(CC) -o pridump pridump.o -L. -lpri -lzap $(CFLAGS)
$(CC) -o pridump pridump.o -L. -lpri $(CFLAGS)
ifneq ($(wildcard .depend),)
include .depend
endif
%.lo : %.c
$(CC) -fPIC $(CFLAGS) -o $@ -c $<
@@ -100,9 +129,10 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
ranlib $(STATIC_LIBRARY)
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
$(CC) -shared -Wl,-soname,libpri.so.1 -o $@ $(DYNAMIC_OBJS)
/sbin/ldconfig $(LDCONFIG_FLAGS) .
$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
$(LDCONFIG) $(LDCONFIG_FLAGS) .
ln -sf libpri.so.1 libpri.so
$(SOSLINK)
clean:
rm -f *.o *.so *.lo *.so.1 *.so.1.0
@@ -113,4 +143,4 @@ clean:
depend: .depend
.depend:
./mkdep ${CFLAGS} `ls *.c`
CC=$(CC) ./mkdep ${CFLAGS} `ls *.c`

5
README
View File

@@ -16,6 +16,11 @@ 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.

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';
}

195
libpri.h
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,37 +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 */
/* Switchtypes 10 - 20 are reserved for internal use */
#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_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_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_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
@@ -173,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
@@ -252,14 +271,20 @@ 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 {
@@ -271,25 +296,38 @@ typedef struct pri_event_facname {
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 useruserinfo[256]; /* User->User info */
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 */
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 {
@@ -298,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 {
@@ -305,9 +345,15 @@ 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 {
@@ -321,6 +367,13 @@ typedef struct pri_event_notify {
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 */
@@ -335,11 +388,15 @@ typedef union {
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
@@ -347,12 +404,28 @@ struct pri_sr;
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 */
@@ -364,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 */
@@ -373,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);
@@ -420,6 +490,9 @@ 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 */
@@ -448,12 +521,33 @@ extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int
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 */
extern void pri_set_message(void (*__pri_error)(char *));
extern void pri_set_error(void (*__pri_error)(char *));
#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
@@ -481,7 +575,50 @@ extern void pri_enslave(struct pri *master, struct pri *slave);
#define PRI_ENSLAVE_SUPPORT
#define PRI_SETUP_CALL
#define PRI_RECEIVE_SUBADDR
#endif
#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

2
mkdep
View File

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

373
pri.c
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>
@@ -19,10 +31,13 @@
#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)
{
@@ -57,18 +72,131 @@ char *pri_switch2str(int sw)
return "GR303 EOC";
case PRI_SWITCH_GR303_TMC:
return "GR303 TMC";
case PRI_SWITCH_QSIG:
return "Q.SIG switch";
default:
return "Unknown switchtype";
}
}
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master)
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;
@@ -78,6 +206,7 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
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;
@@ -88,7 +217,7 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
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);
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
@@ -97,7 +226,7 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
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);
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
@@ -118,9 +247,50 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
return p;
}
struct pri *pri_new(int fd, int node, int switchtype)
void pri_call_set_useruser(q931_call *c, char *userchars)
{
return __pri_new(fd, node, switchtype, NULL);
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)
@@ -140,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:
@@ -152,12 +346,7 @@ 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)
pri_error("Read on %d failed: %s\n", pri->fd, strerror(errno));
return NULL;
}
res = pri->read_func ? pri->read_func(pri, buf, sizeof(buf)) : 0;
if (!res)
return NULL;
/* Receive the q921 packet */
@@ -196,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;
}
@@ -235,6 +424,25 @@ void pri_set_debug(struct pri *pri, int debug)
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)
{
if (!pri || !call)
@@ -308,6 +516,31 @@ int pri_disconnect(struct pri *pri, q931_call *call, int 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)
@@ -336,26 +569,26 @@ void pri_dump_event(struct pri *pri, pri_event *e)
{
if (!pri || !e)
return;
pri_message("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:
pri_message("Error: %s", e->err.err);
pri_message(pri, "Error: %s", e->err.err);
break;
case PRI_EVENT_RESTART:
pri_message("Restart on channel %d\n", e->restart.channel);
pri_message(pri, "Restart on channel %d\n", e->restart.channel);
case PRI_EVENT_RING:
pri_message("Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
pri_message("Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
pri_message("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:
pri_message("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:
pri_message("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);
}
}
@@ -365,10 +598,71 @@ static void pri_sr_init(struct pri_sr *req)
}
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, req);
}
@@ -394,20 +688,20 @@ int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int excl
return q931_setup(pri, c, &req);
}
static void (*__pri_error)(char *stuff);
static void (*__pri_message)(char *stuff);
static void (*__pri_error)(struct pri *pri, char *stuff);
static void (*__pri_message)(struct pri *pri, char *stuff);
void pri_set_message(void (*func)(char *stuff))
void pri_set_message(void (*func)(struct pri *pri, char *stuff))
{
__pri_message = func;
}
void pri_set_error(void (*func)(char *stuff))
void pri_set_error(void (*func)(struct pri *pri, char *stuff))
{
__pri_error = func;
}
void pri_message(char *fmt, ...)
void pri_message(struct pri *pri, char *fmt, ...)
{
char tmp[1024];
va_list ap;
@@ -415,12 +709,12 @@ void pri_message(char *fmt, ...)
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
if (__pri_message)
__pri_message(tmp);
__pri_message(pri, tmp);
else
fputs(tmp, stdout);
}
void pri_error(char *fmt, ...)
void pri_error(struct pri *pri, char *fmt, ...)
{
char tmp[1024];
va_list ap;
@@ -428,7 +722,7 @@ void pri_error(char *fmt, ...)
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
if (__pri_error)
__pri_error(tmp);
__pri_error(pri, tmp);
else
fputs(tmp, stderr);
}
@@ -477,6 +771,12 @@ char *pri_dump_info_str(struct pri *pri)
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);
}
@@ -542,3 +842,12 @@ int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int cal
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 */

View File

@@ -40,8 +40,13 @@ 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 */
@@ -76,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;
@@ -99,6 +106,9 @@ struct pri {
unsigned int q931_txcount;
unsigned int q931_rxcount;
#endif
unsigned char last_invoke; /* Last ROSE invoke ID */
unsigned char sendfacility;
};
struct pri_sr {
@@ -114,11 +124,122 @@ struct pri_sr {
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 10
#define PRI_SWITCH_GR303_TMC_SWITCHING 11
#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);
@@ -128,8 +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(char *fmt, ...);
extern void pri_message(struct pri *pri, char *fmt, ...);
extern void pri_error(char *fmt, ...);
extern void pri_error(struct pri *pri, char *fmt, ...);
void libpri_copy_string(char *dst, const char *src, size_t size);
#endif

View File

@@ -39,9 +39,6 @@
#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
@@ -81,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 {
@@ -101,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 {
@@ -119,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 {
@@ -164,7 +161,7 @@ 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, int now);

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,14 +94,14 @@ 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 {
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)
@@ -208,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
@@ -266,6 +267,8 @@ 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);
@@ -273,7 +276,7 @@ extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callm
extern q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
extern void q931_dump(q931_h *h, int len, int txrx);
extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
extern void __q931_destroycall(struct pri *pri, q931_call *c);

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

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
@@ -67,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);
@@ -103,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;
@@ -124,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);

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) {
pri_error("No more room in scheduler\n");
pri_error(pri, "No more room in scheduler\n");
return -1;
}
if (x > maxsched)
@@ -113,6 +114,6 @@ pri_event *pri_schedule_run(struct pri *pri)
void pri_schedule_del(struct pri *pri,int id)
{
if ((id >= MAX_SCHED) || (id < 0))
pri_error("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;
}

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

177
q921.c
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"
@@ -71,7 +72,7 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
return q921_transmit(pri->master, h, len);
#ifdef RANDOM_DROPS
if (!(random() % 3)) {
pri_message(" === Dropping Packet ===\n");
pri_message(pri, " === Dropping Packet ===\n");
return 0;
}
#endif
@@ -80,11 +81,11 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
#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)) {
pri_error("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);
@@ -107,11 +108,11 @@ static void q921_send_ua(struct pri *pri, int pfbit)
h.h.c_r = 1;
break;
default:
pri_error("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)
pri_message("Sending Unnumbered Acknowledgement\n");
pri_message(pri, "Sending Unnumbered Acknowledgement\n");
q921_transmit(pri, &h, 3);
}
@@ -123,7 +124,7 @@ static void q921_send_sabme(void *vpri, int now)
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_now, pri);
pri->sabme_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], q921_send_sabme_now, pri);
if (!now)
return;
Q921_INIT(pri, h);
@@ -139,11 +140,11 @@ static void q921_send_sabme(void *vpri, int now)
h.h.c_r = 0;
break;
default:
pri_error("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)
pri_message("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;
}
@@ -166,7 +167,7 @@ static int q921_ack_packet(struct pri *pri, int num)
else
pri->txqueue = f->next;
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue ? pri->txqueue->h.n_s : -1);
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);
@@ -180,7 +181,7 @@ static int q921_ack_packet(struct pri *pri, int num)
if (!f->transmitted) {
/* Send it now... */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Finally transmitting %d, since window opened up\n", f->h.n_s);
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;
@@ -206,9 +207,9 @@ 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("-- Restarting T203 counter\n");
pri_message(pri, "-- Restarting 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);
}
}
@@ -221,7 +222,7 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
for (x=pri->v_a; (x != pri->v_s) && (x != ack); Q921_INC(x));
if (x != ack) {
/* ACK was outside of our window --- ignore */
pri_error("ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a, pri->v_s);
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;
@@ -229,33 +230,33 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
}
/* Cancel each packet as necessary */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- ACKing all packets from %d to (but not including) %d\n", pri->v_a, ack);
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)
pri_message("-- 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)
pri_message("-- 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)
pri_message("-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue->h.n_s);
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)
pri_message("-- 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;
}
@@ -277,11 +278,11 @@ static void q921_reject(struct pri *pri, int pf)
h.h.c_r = 1;
break;
default:
pri_error("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)
pri_message("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);
}
@@ -308,12 +309,12 @@ static void q921_rr(struct pri *pri, int pbit, int cmd) {
h.h.c_r = 1;
break;
default:
pri_error("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)
pri_message("Sending Receiver Ready (%d)\n", pri->v_r);
pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r);
q921_transmit(pri, &h, 4);
}
@@ -323,7 +324,7 @@ static void t200_expire(void *vpri)
if (pri->txqueue) {
/* Retransmit first packet in the queue, setting the poll bit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- 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 */
@@ -332,23 +333,23 @@ 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)
pri_message("-- Retransmitting %d bytes\n", pri->txqueue->len);
pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
if (pri->busy)
q921_rr(pri, 1, 0);
q921_rr(pri, 1, 1);
else {
if (!pri->txqueue->transmitted)
pri_error("!! Not good - head of queue has not been transmitted yet\n");
pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
}
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- 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)
pri_message("-- Timeout occured, restarting PRI\n");
pri_message(pri, "-- Timeout occured, restarting PRI\n");
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
@@ -357,15 +358,15 @@ static void t200_expire(void *vpri)
}
} else if (pri->solicitfbit) {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Retrying poll with f-bit\n");
pri_message(pri, "-- Retrying poll with f-bit\n");
pri->retrans++;
if (pri->retrans < N_200) {
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
pri->solicitfbit = 1;
q921_rr(pri, 1, 1);
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)
pri_message("-- Timeout occured, restarting PRI\n");
pri_message(pri, "-- Timeout occured, restarting PRI\n");
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
@@ -373,7 +374,7 @@ static void t200_expire(void *vpri)
pri->schedev = 1;
}
} else {
pri_error("T200 counter expired, nothing to send...\n");
pri_error(pri, "T200 counter expired, nothing to send...\n");
pri->t200_timer = 0;
}
}
@@ -423,26 +424,26 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
f->transmitted++;
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("Delaying transmission of %d, window is %d/%d long\n",
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)
pri_message("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)
pri_message("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)
pri_message("T_200 timer already going (%d)\n", pri->t200_timer);
pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
} else {
pri_error("!! Out of memory for Q.921 transmit\n");
pri_error(pri, "!! Out of memory for Q.921 transmit\n");
return -1;
}
return 0;
@@ -453,16 +454,16 @@ static void t203_expire(void *vpri)
struct pri *pri = vpri;
if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("T203 counter expired, sending RR and scheduling T203 again\n");
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, T_200, t200_expire, pri);
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("T203 counter expired in weird state %d\n", pri->q921_state);
pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
pri->t203_timer = 0;
}
}
@@ -507,7 +508,7 @@ static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len)
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;
@@ -520,7 +521,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
if (buf) {
for (x=0;x<len;x++)
buflen += sprintf(buf + buflen, "%02x ", h->raw[x]);
pri_message("\n%c [ %s]\n", direction_tag, buf);
pri_message(pri, "\n%c [ %s]\n", direction_tag, buf);
free(buf);
}
}
@@ -528,17 +529,17 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
case 0:
case 2:
pri_message("\n%c Informational frame:\n", direction_tag);
pri_message(pri, "\n%c Informational frame:\n", direction_tag);
break;
case 1:
pri_message("\n%c Supervisory frame:\n", direction_tag);
pri_message(pri, "\n%c Supervisory frame:\n", direction_tag);
break;
case 3:
pri_message("\n%c Unnumbered frame:\n", direction_tag);
pri_message(pri, "\n%c Unnumbered frame:\n", direction_tag);
break;
}
pri_message(
pri_message(pri,
"%c SAPI: %02d C/R: %d EA: %d\n"
"%c TEI: %03d EA: %d\n",
direction_tag,
@@ -552,7 +553,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
case 0:
case 2:
/* Informational frame */
pri_message(
pri_message(pri,
"%c N(S): %03d 0: %d\n"
"%c N(R): %03d P: %d\n"
"%c %d bytes of data\n",
@@ -579,7 +580,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
type = "REJ (reject)";
break;
}
pri_message(
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",
@@ -625,7 +626,7 @@ void q921_dump(q921_h *h, int len, int showraw, int txrx)
break;
}
}
pri_message(
pri_message(pri,
"%c M3: %d P/F: %d M2: %d 11: %d [ %s ]\n"
"%c %d bytes of data\n",
direction_tag,
@@ -656,7 +657,7 @@ static pri_event *q921_dchannel_up(struct pri *pri)
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;
@@ -680,7 +681,7 @@ 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);
@@ -708,23 +709,23 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
case 0:
case 2:
if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {
pri_error("!! 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) {
pri_error("!! Received short I-frame (expected 4, got %d)\n", len);
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) {
pri_error("!! Got S-frame while link down\n");
pri_error(pri, "!! Got S-frame while link down\n");
return NULL;
}
if (len < 4) {
pri_error("!! Received short S-frame (expected 4, got %d)\n", len);
pri_error(pri, "!! Received short S-frame (expected 4, got %d)\n", len);
break;
}
switch(h->s.ss) {
@@ -739,10 +740,10 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
/* 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)
pri_message("-- 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)
pri_message("-- Unsolicited RR with P/F bit, responding\n");
pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
q921_rr(pri, 1, 0);
}
pri->solicitfbit = 0;
@@ -751,7 +752,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- 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);
@@ -761,7 +762,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- 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, 0);
@@ -773,7 +774,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
/* Matches the request, or follows in our window, and has
already been transmitted. */
sendnow = 1;
pri_error("!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
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);
}
@@ -782,11 +783,11 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
pri_error("!! 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("!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
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 */
@@ -797,18 +798,18 @@ static pri_event *__q921_receive_qualified(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:
pri_error("!! 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) {
pri_error("!! Received short unnumbered frame\n");
pri_error(pri, "!! Received short unnumbered frame\n");
break;
}
switch(h->u.m3) {
@@ -818,7 +819,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
/* Section 5.7.1 says we should restart on receiving a DM response with the f-bit set to
one, but we wait T200 first */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Got DM Mode from peer.\n");
pri_message(pri, "-- Got DM Mode from peer.\n");
/* Disconnected mode, try again after T200 */
ev = q921_dchannel_down(pri);
q921_start(pri, 0);
@@ -826,7 +827,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Ignoring unsolicited DM with p/f set to 0\n");
pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
#if 0
/* Requesting that we start */
q921_start(pri, 0);
@@ -834,12 +835,12 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
}
break;
} else if (!h->u.m2) {
pri_message("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)
pri_message("-- Got Disconnect from peer.\n");
pri_message(pri, "-- Got Disconnect from peer.\n");
/* Acknowledge */
q921_send_ua(pri, h->u.p_f);
ev = q921_dchannel_down(pri);
@@ -849,7 +850,7 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
if (h->u.m2 == 3) {
/* SABME */
if (pri->debug & PRI_DEBUG_Q921_STATE) {
pri_message("-- 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;
@@ -871,22 +872,22 @@ static pri_event *__q921_receive_qualified(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) {
pri_message("-- 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
pri_error("!! 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
pri_error("!! 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:
pri_error("!! Frame got rejected!\n");
pri_error(pri, "!! Frame got rejected!\n");
break;
case 5:
pri_error("!! XID frames not supported\n");
pri_error(pri, "!! XID frames not supported\n");
break;
default:
pri_error("!! 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;
@@ -901,7 +902,7 @@ static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
len -= 2;
if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
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))
@@ -940,7 +941,7 @@ pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
void q921_start(struct pri *pri, int now)
{
if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
pri_error("!! 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 */

1447
q931.c

File diff suppressed because it is too large Load Diff

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
@@ -44,13 +44,20 @@
#include <sys/socket.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#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
@@ -78,14 +85,40 @@ static void event1(struct pri *pri, pri_event *e)
sprintf(dest, "60%02d", x + 1);
if (!(calls[x] = pri_new_call(pri))) {
perror("pri_new_call");
} else if (pri_call(pri, calls[x], PRI_TRANS_CAP_DIGITAL, x + 1, 1, 1, num,
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);
}
@@ -95,6 +128,19 @@ 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);
@@ -163,7 +209,7 @@ static void *dchan(void *data)
fd_set fds;
int res;
for(;;) {
if (next == pri_schedule_next(pri)) {
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;