Compare commits

...

27 Commits

Author SHA1 Message Date
Matthew Fredrickson
11206c4ddf git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.2@1165 2fbb986a-6c06-0410-b554-c9c1f0a7f128 2009-10-08 19:58:50 +00:00
Matthew Fredrickson
30a3abe6c5 Update .version file and Changelog correctly this time...
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.2@1164 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-10-08 19:56:28 +00:00
Matthew Fredrickson
eb34562959 This fix is more like the fix that was used to resolve the issue for the PRI case
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.2@1144 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-09-29 15:32:23 +00:00
Matthew Fredrickson
fd30b495b6 Changes for 1.4.10.2
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.2@1143 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-09-28 19:07:01 +00:00
Matthew Fredrickson
48f28055e4 git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.2@1142 2fbb986a-6c06-0410-b554-c9c1f0a7f128 2009-09-28 18:52:56 +00:00
Shaun Ruffell
7659b102d4 Limiting last entry to 80 columns
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.1@936 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-07-02 19:15:01 +00:00
Shaun Ruffell
b0180e3283 Update the .version file to 1.4.10.1
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.1@935 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-07-02 19:09:43 +00:00
Matthew Fredrickson
b6d92b91b4 git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.1@929 2fbb986a-6c06-0410-b554-c9c1f0a7f128 2009-06-30 15:43:39 +00:00
Matthew Fredrickson
fe23002233 ------------------------------------------------------------------------
r859 | mattf | 2009-06-09 14:47:05 -0500 (Tue, 09 Jun 2009) | 19 lines

There are two changes in this commit that are bug fixes for various Q.921 issues found in internal testing.

Both were exposed/introduced by the TBR4 compliance patch for bug #12861, in changing how retransmissions and in how
the transmission queue was maintained.  TX-RX message flow and acknowledgement was severely restricted,
since the patch changed the behavior so that pending untransmitted frames would not actually be send until
the next RR was received in normal circumstances, or REJ when a reject frame was received.  On busy links,
this can severly limit the amount of useful traffic that is sent, and can slow down message transmission.

Until someone can point out where in Q.921 it is mandated for us to wait for RR frames to start sending
untransmitted messages, the first change is to allow us to send untransmitted frames when we receive new
I frames as well, with updated N(R).

The other bug fixed is a situation caused by the restricted traffic flow, if an outside process tries to send
an I-frame asynchronous to an RR frame, when the transmit window was previously closed and then opened up but 
an RR has not been received yet.  A bug was found with the integration of the old transmit code with the new reject 
handling code which caused the new frame to be sent immediately, regardless if there were any pending untransmitted 
I-frames in the queue to be sent and causing an out of order I-frame to be sent to the other side.  This bug is 
also fixed in this patch.

------------------------------------------------------------------------


git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.1@928 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-06-30 15:37:25 +00:00
Matthew Fredrickson
09eb3b1453 git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10.1@927 2fbb986a-6c06-0410-b554-c9c1f0a7f128 2009-06-30 15:34:46 +00:00
Matthew Fredrickson
a12412eec8 Importing files for 1.4.10 release.
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10@761 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-04-18 21:27:42 +00:00
Matthew Fredrickson
d681c61357 Creating tag for the release of libpri-1.4.10
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10@760 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-04-18 21:26:56 +00:00
Matthew Fredrickson
26ced75a26 Importing files for 1.4.10 release.
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10@758 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-04-18 21:26:07 +00:00
Matthew Fredrickson
9757b33103 Creating tag for the release of libpri-1.4.10
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.10@757 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-04-18 21:25:41 +00:00
Richard Mudgett
f9d5aa3c3a Comment changes and some string content corrections.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@726 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-04-02 19:33:38 +00:00
Richard Mudgett
88551af7ef Comment changes to note what ISDN message type causes the event.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@715 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-03-26 16:01:45 +00:00
Richard Mudgett
29ded17c0b Added pSS1InfoElement comments in qsig_cf_callrerouting().
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@711 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-03-19 01:39:21 +00:00
Richard Mudgett
bbaeec9513 Use the correct branch integrated property when generating the version string.
Update the make_version file to the latest Asterisk version with the
appropriate libpri required chage.


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@705 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-03-13 01:05:54 +00:00
Joshua Colp
48fc219865 Make sure we only have 4 octects on unrestricted 64k data calls.
(closes issue #14507)
Reported by: jsmith
Patches:
      64k-data.patch uploaded by jsmith (license 15)
Tested by: jsmith
(closes issue #13118)
Reported by: radpeter


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@701 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-03-04 20:31:20 +00:00
Leif Madsen
9ecdbed001 Fix a small spelling error.
(closes issue #14375)
Reported by: jeremy1

git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@687 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-02-02 20:18:03 +00:00
Matthew Fredrickson
3d91cd5e30 A couple of last BRI fixes in libpri... don't discard pending iframes when we call the q921_dchannel_up routine, since we need to be able to send the ones that were queued up while the D-channel went down and is being reactivated. Also fix some buggy logic in the frame transmission decision code.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@680 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-01-27 23:22:06 +00:00
Matthew Fredrickson
a30eeee9a8 Change behavior so that we do not send I-frames when link is down, but instead queue them up until the link comes up and send them out then.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@675 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-01-22 21:48:41 +00:00
Matthew Fredrickson
07c4195876 Add additional case where T200 expires greater than N200 times and we need to release and reacquire the TEI.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@656 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2009-01-09 17:58:28 +00:00
Matthew Fredrickson
40ae2a030a Add some additional debug for Q.921 MDL messages as well as fix a bug in RESTART messages on BRI
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@653 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-12-23 21:38:25 +00:00
Matthew Fredrickson
2c104c4dbd Fix a number of Q.921 bugs, found doing TBR4 compliance testing, thanks to Tzafrir, Xorcom, and co. (#12861). Thanks!
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@645 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-11-22 00:34:26 +00:00
Matthew Fredrickson
e1bfec4b1e Merging in additional Q.SIG features in #13454. Includes Q.SIG physical/logical channel mapping support, extended coding of Q.SIG name operations (calling name), and call rerouting support via added dialplan application.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@636 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-10-17 16:13:42 +00:00
Jason Parker
aeb5a6d284 Make install paths use libdir, like libss7
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@616 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-08-06 18:20:51 +00:00
13 changed files with 1147 additions and 221 deletions

1
.version Normal file
View File

@@ -0,0 +1 @@
1.4.10.2

476
ChangeLog Normal file
View File

@@ -0,0 +1,476 @@
2009-10-08 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.10.2 released. A bug was found which was introduced
during the PTMP rewrite, which causes timers to not be cleared
before being set in certain situations. This can cause the
scheduler to be completely filled, as well as improper Q.921 link
operation.
2009-04-18 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.10.1 released. Includes a fix for a regression found in
the last few revisions of libpri, but fixed in revision 859 of
branches/1.4. The summary is as follows:
* q921.c: There are two changes in this commit that are bug fixes for
various Q.921 issues found in internal testing.
Both were exposed/introduced by the TBR4 compliance patch for bug
#12861, in changing how retransmissions and in how the transmission
queue was maintained. TX-RX message flow and acknowledgement was
severely restricted, since the patch changed the behavior so that
pending untransmitted frames would not actually be send until the
next RR was received in normal circumstances, or REJ when a reject
frame was received. On busy links, this can severly limit the
amount of useful traffic that is sent, and can slow down message
transmission.
Until someone can point out where in Q.921 it is mandated for us to
wait for RR frames to start sending untransmitted messages, the
first change is to allow us to send untransmitted frames when we
receive new I frames as well, with updated N(R).
The other bug fixed is a situation caused by the restricted traffic
flow, if an outside process tries to send an I-frame asynchronous to
an RR frame, when the transmit window was previously closed and then
opened up but an RR has not been received yet. A bug was found with
the integration of the old transmit code with the new reject
handling code which caused the new frame to be sent immediately,
regardless if there were any pending untransmitted I-frames in the
queue to be sent and causing an out of order I-frame to be sent to
the other side. This bug is also fixed in this patch.
2009-04-18 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.10 released.
2009-04-02 19:33 +0000 [r726] Richard Mudgett <rmudgett@digium.com>
* pri_facility.c: Comment changes and some string content
corrections.
2009-03-26 16:01 +0000 [r715] Richard Mudgett <rmudgett@digium.com>
* libpri.h: Comment changes to note what ISDN message type causes
the event.
2009-03-19 01:39 +0000 [r711] Richard Mudgett <rmudgett@digium.com>
* pri_facility.c: Added pSS1InfoElement comments in
qsig_cf_callrerouting().
2009-03-13 01:05 +0000 [r705] Richard Mudgett <rmudgett@digium.com>
* build_tools/make_version: Use the correct branch integrated
property when generating the version string. Update the
make_version file to the latest Asterisk version with the
appropriate libpri required chage.
2009-03-04 20:31 +0000 [r701] Joshua Colp <jcolp@digium.com>
* q931.c: Make sure we only have 4 octects on unrestricted 64k data
calls. (closes issue #14507) Reported by: jsmith Patches:
64k-data.patch uploaded by jsmith (license 15) Tested by: jsmith
(closes issue #13118) Reported by: radpeter
2009-02-02 20:18 +0000 [r687] Leif Madsen <lmadsen@digium.com>
* libpri.h: Fix a small spelling error. (closes issue #14375)
Reported by: jeremy1
2009-01-27 23:22 +0000 [r680] Matthew Fredrickson <creslin@digium.com>
* q921.c: A couple of last BRI fixes in libpri... don't discard
pending iframes when we call the q921_dchannel_up routine, since
we need to be able to send the ones that were queued up while the
D-channel went down and is being reactivated. Also fix some buggy
logic in the frame transmission decision code.
2009-01-22 21:48 +0000 [r675] Matthew Fredrickson <creslin@digium.com>
* q921.c: Change behavior so that we do not send I-frames when link
is down, but instead queue them up until the link comes up and
send them out then.
2009-01-09 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.9 released.
2009-01-09 17:58 +0000 [r656] Matthew Fredrickson <creslin@digium.com>
* q921.c: Add additional case where T200 expires greater than N200
times and we need to release and reacquire the TEI.
2008-12-23 21:38 +0000 [r653] Matthew Fredrickson <creslin@digium.com>
* q921.c, q931.c: Add some additional debug for Q.921 MDL messages
as well as fix a bug in RESTART messages on BRI
2008-11-22 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.8 released.
2008-11-22 00:34 +0000 [r645] Matthew Fredrickson <creslin@digium.com>
* q921.c: Fix a number of Q.921 bugs, found doing TBR4 compliance
testing, thanks to Tzafrir, Xorcom, and co. (#12861). Thanks!
2008-10-17 16:13 +0000 [r636] Matthew Fredrickson <creslin@digium.com>
* pri.c, pri_internal.h, pri_q931.h, q931.c, pri_facility.c,
pri_facility.h, libpri.h: Merging in additional Q.SIG features in
#13454. Includes Q.SIG physical/logical channel mapping support,
extended coding of Q.SIG name operations (calling name), and call
rerouting support via added dialplan application.
2008-08-06 18:20 +0000 [r616] Jason Parker <jparker@digium.com>
* Makefile: Make install paths use libdir, like libss7
2008-08-05 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.7 released.
2008-08-05 22:18 +0000 [r611] Kevin P. Fleming <kpfleming@digium.com>
* pritest.c, pri.c, pri_internal.h, q921.c, q931.c, copy_string.c,
prisched.c, pri_q921.h, pri_q931.h, pri_facility.c, /,
compiler.h, pridump.c, testprilib.c, pri_timers.h,
pri_facility.h, libpri.h: Merged revisions 610 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r610
| kpfleming | 2008-08-05 17:16:58 -0500 (Tue, 05 Aug 2008) | 2
lines clean up license headers, and explicitly grant additional
permissions when used with Asterisk ........
2008-07-30 15:43 +0000 [r606-607] Kevin P. Fleming <kpfleming@digium.com>
* /: update ignore list
* Makefile, mkdep (removed): use better version.c creation process,
and better dependency tracking process too
2008-07-29 22:47 +0000 [r598-602] Jason Parker <jparker@digium.com>
* build_tools/make_version: I believe this is what was meant. (it
matches how Asterisk does it)
* build_tools/make_version: libpri is not libss7 :D
2008-07-22 22:36 +0000 [r594] Kevin P. Fleming <kpfleming@digium.com>
* pri_internal.h, libpri.h: correct comments to match code
2008-07-22 Kevin P. Fleming <kpfleming@digium.com>
* Libpri 1.4.6 released.
2008-07-22 19:43 +0000 [r589] Kevin P. Fleming <kpfleming@digium.com>
* pri.c, pri_internal.h, q931.c, libpri.h: rename API call and
option (nothing has been released to use it yet so this should be
safe) to be more accurate in describing what it does (closes
issue #13042)
2008-07-11 Jason Parker <jparker@digium.com>
* Libpri 1.4.5 released.
2008-07-11 16:44 +0000 [r574-579] Kevin P. Fleming <kpfleming@digium.com>
* /: ignore generated files
* pri.c, pri_internal.h, q931.c, libpri.h: modify work done for
issue #10552, making the support of inband audio after RELEASE a
configurable option, since it is causing problems for a number of
users (closes issue #13042)
2008-06-04 17:02 +0000 [r562] Dwayne M. Hubbard <dhubbard@digium.com>
* q931.c: While working on issue 3450 I noticed that the
information channel selection field in the channel identification
IE was displayed incorrectly when using 'pri intense debug'. I
wanted another pair of eyes to look at the code because
everything looked correct until Shaun Ruffell noticed the missing
comma in the msg_chan_sel array.
2008-05-07 19:51 +0000 [r557] Matthew Fredrickson <creslin@digium.com>
* pri.c, pritest.c, pri_internal.h, pri_q921.h, Makefile, q921.c,
q931.c, pri_facility.c, prisched.c, testprilib.c, pri_timers.h,
pri_facility.h, libpri.h: Moving trunk changes back into 1.4
2008-05-07 Matthew Fredrickson <creslin@digium.com>
* Libpri 1.4.4 released.
2008-05-06 16:43 +0000 [r553-555] Matthew Fredrickson <creslin@digium.com>
* q921.c, pri.c: Remove some unnecessary debug messages
* q931.c: We passed TBR3 layer 2 and layer 3 testing with this
commit in for BRI-TE PTMP.
* q931.c: Final patch to pass certification
2008-04-22 15:30 +0000 [r546] Russell Bryant <russell@digium.com>
* Makefile: All versions of libpri have been installed as
libpri.so.1.0, even though the API and ABI have changed over
time. This patch changes the Makefile to install the library as
libpri.so.1.4 to indicate that this is not compatible with
previous versions. In the future, this should be changed as we
make ABI changes. (closes issue #10376) Reported by: tzafrir
Patches: libpri-soname.diff uploaded by tzafrir (license 46) --
with very minor changes by me
2008-03-15 19:57 +0000 [r541-543] Matthew Fredrickson <creslin@digium.com>
* libpri.h, pri.c: Remove some useless event items
* q921.c, pri_internal.h: Make sure if we're a bri and in PTMP mode
that we release the TEI and try to get a new one with the other
end when we lose activity in multiframe mode
* q921.c, pri.c, pri_q921.h: When we recieve a UA in any TEI
established state other than awaiting establishement make sure we
drop the TEI and get a new one. For passing tests PC37.2 - PC41.2
in Q.921
2008-03-06 23:43 +0000 [r538-539] Matthew Fredrickson <creslin@digium.com>
* q921.c: Make sure we are sending as command not as response
* q921.c: Make sure C/R bit is correct
2008-03-01 23:30 +0000 [r531-535] Matthew Fredrickson <creslin@digium.com>
* q921.c: Remove some (currently) useless code
* q921.c, pri.c, pri_internal.h: Some more updates to add code for
passing PC 27.1 in Q.921
* q921.c, pri.c: Various coding style cleanups as well as a bug fix
for TEI removal
* q921.c, q931.c, pri.c, pri_internal.h: Initial checkin of code to
pass Q.921 PC25 and PC26
* q921.c: Add support for responding to TEI requests (Q.921 PC23.x)
2008-02-18 20:31 +0000 [r525] Matthew Fredrickson <creslin@digium.com>
* q931.c, libpri.h: Improve transmission, receiving, and dumping of
bearer capability IE (#11593)
2008-01-16 18:06 +0000 [r518] Jason Parker <jparker@digium.com>
* Makefile, /: Add logging for 'make update' command (also fixes
updates in some places). Issue #11766, initial patch by jmls.
2007-12-26 17:35 +0000 [r505] Russell Bryant <russell@digium.com>
* libpri.h: Remove unnecessary usage of the extern keyword.
2007-12-06 22:16 +0000 [r494-496] Russell Bryant <russell@digium.com>
* q921.c, q931.c, pri_facility.c, pri.c: Change malloc+memset to
calloc. Also, handle allocation failures early to reduce
indentation. (closes issue #11469) Reported by: eliel Patches:
pri.c.patch uploaded by eliel (license 64) q931.c.patch uploaded
by eliel (license 64) q921.c.patch uploaded by eliel (license 64)
pri_facility.c.patch uploaded by eliel (license 64)
* pri.c: Change a use of malloc+memset to calloc. Also, reduce
indentation of a function by doing the check for memory
allocation failure at the beginning.
* pri.c: Change the table used to hold the default timers to be
global and const, instead of allocating it on the stack each time
the function is called.
2007-12-05 00:20 +0000 [r491-493] Matthew Fredrickson <creslin@digium.com>
* q931.c: Improve the parameter name to better reflect its use
* q921.c, q931.c: More PTMP fixes. Stand by, more changes to come
* q921.c, q931.c, testprilib.c: More magic to make BRI CPE PTMP
work
2007-11-21 22:30 +0000 [r486-487] Matthew Fredrickson <creslin@digium.com>
* q931.c: Make sure we loop BRI call references for one byte CREFs
instead of two
* q921.c, q931.c, libpri.h, pri.c, pritest.c, pri_internal.h: Add
BRI support to libpri
2007-10-13 16:00 +0000 [r473] Matthew Fredrickson <creslin@digium.com>
* q921.c: Make sure that we only output the message handling debug
when we're actually debugging
2007-09-25 21:56 +0000 [r469] Matthew Fredrickson <creslin@digium.com>
* q931.c: Fix user-user IE order in setup message (#10705)
2007-06-20 15:18 +0000 [r428-430] Matthew Fredrickson <creslin@digium.com>
* Makefile: Revert that back to how it was
* Makefile, q921.c, q931.c, prisched.c, testprilib.c, pri_timers.h,
libpri.h, pri.c, pri_internal.h, pri_q921.h: Patch to add PTMP
mode (BRI support)
2007-06-06 21:59 +0000 [r417-425] Matthew Fredrickson <creslin@digium.com>
* q931.c, pri_facility.c, pri_facility.h, pri.c, pri_internal.h:
Preliminary patch plus mods for Q.SIG Path Replacement (Q.SIG
version of 2BCT) #7778
2007-05-25 17:36 +0000 [r413] Matthew Fredrickson <creslin@digium.com>
* q931.c, pri_facility.c, pri_facility.h, libpri.h: Commit path for
ROSE-12 and ROSE-13 support (#9076)
2006-11-03 18:16 +0000 [r382] Matthew Fredrickson <creslin@digium.com>
* q921.c: Remove pointless recursion. (#8281)
2008-05-07 19:51 +0000 [r557] Matthew Fredrickson <creslin@digium.com>
* pri.c, pritest.c, pri_internal.h, pri_q921.h, Makefile, q921.c,
q931.c, pri_facility.c, prisched.c, testprilib.c, pri_timers.h,
pri_facility.h, libpri.h: Moving trunk changes back into 1.4
2008-05-02 20:21 +0000 [r552] Brett Bryant <bbryant@digium.com>
* Makefile, build_tools (added), build_tools/make_version (added),
build_tools/make_version_c (added), libpri.h: Add new API call
(pri_get_version) to show the current version of the branch for
support purposes.
2008-04-16 00:21 +0000 [r544] Kevin P. Fleming <kpfleming@digium.com>
* q921.c: fix the indentation in this function so that it is
actually possible to read it and understand the logic and flow
2008-02-21 16:38 +0000 [r528] Joshua Colp <jcolp@digium.com>
* q931.c: If inband audio is being provided with a disconnect
message let the audio be heard before releasing the channel.
(closes issue #10552) Reported by: paravoid Patches:
disconnect-audio.diff uploaded by paravoid (license 200)
2008-02-18 20:31 +0000 [r524] Matthew Fredrickson <creslin@digium.com>
* q931.c, libpri.h: Improve transmission, receiving, and dumping of
bearer capability IE (#11593)
2008-01-11 16:34 +0000 [r514] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 513 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r513
| mattf | 2008-01-11 10:33:52 -0600 (Fri, 11 Jan 2008) | 1 line
We should not be parsing further into the bearer capability IE if
the length does not confirm that there actually is data present
........
2007-12-13 Russell Bryant <russell@digium.com>
* libpri 1.4.3 released.
2007-10-22 15:10 +0000 [r479] Kevin P. Fleming <kpfleming@digium.com>
* pri_internal.h, /: Merged revisions 478 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r478
| kpfleming | 2007-10-22 10:09:27 -0500 (Mon, 22 Oct 2007) | 3
lines we need to include stddef.h for 'size_t' ........
2007-10-16 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.2 released.
2007-10-05 16:45 +0000 [r470] Jason Parker <jparker@digium.com>
* libpri.h: Fix an incorrect pri_event structure definition. Issue
10832, patch by flefoll
2007-09-25 21:37 +0000 [r468] Matthew Fredrickson <creslin@digium.com>
* q931.c: Fix user-user IE order in setup message (#10705)
2007-09-14 21:32 +0000 [r465] Matthew Fredrickson <creslin@digium.com>
* q931.c, libpri.h: Fix for #10189. Make sure we properly report
the user layer 1 for H.223 and H.245
2007-09-06 15:11 +0000 [r462] Matthew Fredrickson <creslin@digium.com>
* pri.c, pri_facility.c, /: Merged revisions 460 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r460
| mattf | 2007-09-06 10:06:42 -0500 (Thu, 06 Sep 2007) | 1 line
TBCT now works. It should work for NI2, 4E, and 5E. This code was
tested on NI2. ........
2007-08-27 19:21 +0000 [r446] Jason Parker <jparker@digium.com>
* Makefile, /: Merged revisions 445 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r445
| qwell | 2007-08-27 14:20:23 -0500 (Mon, 27 Aug 2007) | 2 lines
Make sure we build both the static and shared modules with -fPIC.
........
2007-08-06 19:58 +0000 [r441] Jason Parker <jparker@digium.com>
* Makefile: Allow setting CC to something with a space, such as
`make CC="gcc -m32"` Issue 10253.
2007-07-09 Russell Bryant <russell@digium.com>
* libpri 1.4.1 released.
2007-06-19 18:23 +0000 [r427] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 426 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r426
| mattf | 2007-06-19 13:22:33 -0500 (Tue, 19 Jun 2007) | 1 line
Try to send pending facility messages if we receive alerting (for
when we don't get proceeding) (#9651) ........
2007-06-06 21:58 +0000 [r416-424] Matthew Fredrickson <creslin@digium.com>
* pri_facility.c, /: Merged revisions 423 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r423
| mattf | 2007-06-06 16:57:15 -0500 (Wed, 06 Jun 2007) | 1 line
Oops, that should not be on one line ........
* pri_facility.c, /: Merged revisions 415 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r415
| mattf | 2007-06-06 08:20:05 -0500 (Wed, 06 Jun 2007) | 2 lines
Make sure we only send the NFE when we are talking QSIG ........
2007-01-22 22:29 +0000 [r390] Matthew Fredrickson <creslin@digium.com>
* q931.c, /: Merged revisions 389 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r389
| mattf | 2007-01-22 16:20:59 -0600 (Mon, 22 Jan 2007) | 2 lines
Make sure we send DISCONNECT if we reached the active state and a
call is disconnected, regardless of cause code. ........
2006-12-30 19:17 +0000 [r386] Joshua Colp <jcolp@digium.com>
* Makefile, /: Merged revisions 385 via svnmerge from
https://origsvn.digium.com/svn/libpri/branches/1.2 ........ r385
| file | 2006-12-30 14:16:17 -0500 (Sat, 30 Dec 2006) | 2 lines
Specify full path to restorecon instead of assuming it will be
available from what is in $PATH. (issue #8670 reported by djflux)
........
2006-12-23 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.0 released.
2006-09-20 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.0-beta1 released.

View File

@@ -46,6 +46,7 @@ DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo v
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS)
INSTALL_PREFIX=$(DESTDIR)
INSTALL_BASE=/usr
libdir?=$(INSTALL_BASE)/lib
SOFLAGS:=-Wl,-h$(DYNAMIC_LIBRARY)
LDCONFIG = /sbin/ldconfig
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX))
@@ -96,27 +97,27 @@ update:
fi
install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
mkdir -p $(INSTALL_PREFIX)$(libdir)
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 /sbin/restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib; fi
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(libdir)/$(DYNAMIC_LIBRARY); fi
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
else
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 644 $(STATIC_LIBRARY)
install -f $(INSTALL_PREFIX)$(libdir) -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -f $(INSTALL_PREFIX)$(libdir) -m 644 $(STATIC_LIBRARY)
endif
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.a
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.a
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
pritest: pritest.o

View File

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

View File

@@ -64,23 +64,23 @@
/* 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_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_RING 5 /* Incoming call (SETUP) */
#define PRI_EVENT_HANGUP 6 /* Call got hung up (RELEASE/RELEASE_COMPLETE/other) */
#define PRI_EVENT_RINGING 7 /* Call is ringing (ALERTING) */
#define PRI_EVENT_ANSWER 8 /* Call has been answered (CONNECT) */
#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_RESTART_ACK 10 /* Restart complete on a given channel (RESTART_ACKNOWLEDGE) */
#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_INFO_RECEIVED 12 /* Additional info (digits) received (INFORMATION) */
#define PRI_EVENT_PROCEEDING 13 /* When we get CALL_PROCEEDING */
#define PRI_EVENT_SETUP_ACK 14 /* When we get SETUP_ACKNOWLEDGE */
#define PRI_EVENT_HANGUP_REQ 15 /* Requesting the higher layer to hangup */
#define PRI_EVENT_NOTIFY 16 /* Notification received */
#define PRI_EVENT_PROGRESS 17 /* When we get CALL_PROCEEDING or PROGRESS */
#define PRI_EVENT_KEYPAD_DIGIT 18 /* When we receive during ACTIVE state */
#define PRI_EVENT_HANGUP_REQ 15 /* Requesting the higher layer to hangup (DISCONNECT) */
#define PRI_EVENT_NOTIFY 16 /* Notification received (NOTIFY) */
#define PRI_EVENT_PROGRESS 17 /* When we get PROGRESS */
#define PRI_EVENT_KEYPAD_DIGIT 18 /* When we receive during ACTIVE state (INFORMATION) */
/* Simple states */
#define PRI_STATE_DOWN 0
@@ -595,7 +595,7 @@ int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
/* Set a call has a call indpendent signalling connection (i.e. no bchan) */
int pri_sr_set_connection_call_independent(struct pri_sr *req);
/* Send an MWI indication to a remote location. If activate is non zero, activates, if zero, decativates */
/* Send an MWI indication to a remote location. If activate is non zero, activates, if zero, deactivates */
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 */
@@ -615,6 +615,10 @@ void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
#define PRI_SET_OVERLAPDIAL
void pri_set_overlapdial(struct pri *pri,int state);
/* QSIG logical channel mapping option, do not skip channel 16 */
#define PRI_SET_CHAN_MAPPING_LOGICAL
void pri_set_chan_mapping_logical(struct pri *pri, int state);
#define PRI_DUMP_INFO_STR
char *pri_dump_info_str(struct pri *pri);
@@ -622,9 +626,12 @@ char *pri_dump_info_str(struct pri *pri);
int pri_fd(struct pri *pri);
#define PRI_PROGRESS
/* Send call proceeding */
/* Send progress */
int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
/* Send progress with cause IE */
int pri_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause);
#define PRI_PROCEEDING_FULL
/* Send call proceeding */
int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
@@ -647,6 +654,8 @@ void pri_enslave(struct pri *master, struct pri *slave);
/* Send notification */
int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason);
/* Get/Set PRI Timers */
#define PRI_GETSET_TIMERS
int pri_set_timer(struct pri *pri, int timer, int value);

27
pri.c
View File

@@ -280,7 +280,7 @@ int pri_restart(struct pri *pri)
{
/* Restart Q.921 layer */
if (pri) {
q921_reset(pri);
q921_reset(pri, 1);
q921_start(pri, pri->localtype == PRI_CPE);
}
return 0;
@@ -483,10 +483,19 @@ int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
return q931_call_proceeding(pri, call, channel, info);
}
int pri_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause)
{
if (!pri || !call)
return -1;
return q931_call_progress_with_cause(pri, call, channel, info, cause);
}
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_call_progress(pri, call, channel, info);
}
@@ -505,6 +514,15 @@ int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits)
return q931_keypad_facility(pri, call, digits);
}
int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason)
{
if (!pri || !call)
return -1;
return qsig_cf_callrerouting(pri, call, dest, original, reason);
}
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
@@ -787,6 +805,12 @@ void pri_set_overlapdial(struct pri *pri,int state)
pri->overlapdial = state;
}
void pri_set_chan_mapping_logical(struct pri *pri, int state)
{
if (pri->switchtype == PRI_SWITCH_QSIG)
pri->chan_mapping_logical = state;
}
void pri_set_inbanddisconnect(struct pri *pri, unsigned int enable)
{
pri->acceptinbanddisconnect = (enable != 0);
@@ -830,6 +854,7 @@ 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, "Logical Channel Mapping: %d\n", pri->chan_mapping_logical);
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]);

View File

@@ -1186,6 +1186,198 @@ int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
}
/* End EECT */
/* QSIG CF CallRerouting */
int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason)
{
/*CallRerouting ::= OPERATION
-- Sent from the Served User PINX to the Rerouting PINX
ARGUMENT SEQUENCE
{ reroutingReason DiversionReason,
originalReroutingReason [0] IMPLICIT DiversionReason OPTIONAL,
calledAddress Address,
diversionCounter INTEGER (1..15),
pSS1InfoElement PSS1InformationElement,
-- The basic call information elements Bearer capability, High layer compatibility, Low
-- layer compatibity, Progress indicator and Party category can be embedded in the
-- pSS1InfoElement in accordance with 6.5.3.1.5
lastReroutingNr [1] PresentedNumberUnscreened,
subscriptionOption [2] IMPLICIT SubscriptionOption,
callingPartySubaddress [3] PartySubaddress OPTIONAL,
callingNumber [4] PresentedNumberScreened,
callingName [5] Name OPTIONAL,
originalCalledNr [6] PresentedNumberUnscreened OPTIONAL,
redirectingName [7] Name OPTIONAL,
originalCalledName [8] Name OPTIONAL,
extension CHOICE {
[9] IMPLICIT Extension ,
[10] IMPLICIT SEQUENCE OF Extension } OPTIONAL }
*/
int i = 0, j;
int res = 0;
unsigned char buffer[255] = "";
int len = 253;
struct rose_component *comp = NULL, *compstk[10];
int compsp = 0;
static unsigned char op_tag[] = {
0x13,
};
buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
/* Interpretation component */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
ASN1_PUSH(compstk, compsp, comp);
ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2); /* reject - to get feedback from QSIG switch */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
ASN1_PUSH(compstk, compsp, comp);
ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
res = asn1_string_encode(ASN1_INTEGER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
if (res < 0)
return -1;
i += res;
/* call rerouting argument */
ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* reroutingReason DiversionReason */
if (reason) {
if (!strcasecmp(reason, "cfu"))
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1); /* cfu */
else if (!strcasecmp(reason, "cfb"))
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 2); /* cfb */
else if (!strcasecmp(reason, "cfnr"))
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3); /* cfnr */
} else {
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0); /* unknown */
}
/* calledAddress Address */
/* explicit sequence tag for Address */
ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* implicit choice public party number tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* type of public party number = unknown */
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
/* NumberDigits of public party number */
j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, (char*)dest, strlen(dest));
if (j < 0)
return -1;
i += j;
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
/* diversionCounter INTEGER (1..15) */
ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);
/* pSS1InfoElement */
ASN1_ADD_SIMPLE(comp, (ASN1_APPLICATION | ASN1_TAG_0 ), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
buffer[i++] = (0x04); /* Bearer Capability IE */
buffer[i++] = (0x03); /* len */
buffer[i++] = (0x80); /* ETSI Standard, Speech */
buffer[i++] = (0x90); /* circuit mode, 64kbit/s */
buffer[i++] = (0xa3); /* level1 protocol, a-law */
buffer[i++] = (0x95); /* locking shift to codeset 5 (national use) */
buffer[i++] = (0x32); /* Unknown ie */
buffer[i++] = (0x01); /* Unknown ie len */
buffer[i++] = (0x81); /* Unknown ie body */
ASN1_FIXUP(compstk, compsp, buffer, i);
/* lastReroutingNr [1]*/
/* implicit optional lastReroutingNr tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* implicit choice presented number unscreened tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* implicit choice public party number tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* type of public party number = unknown */
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, original?(char*)original:c->callednum, original?strlen(original):strlen(c->callednum));
if (j < 0)
return -1;
i += j;
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
/* subscriptionOption [2]*/
/* implicit optional lastReroutingNr tag */
ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0); /* noNotification */
/* callingNumber [4]*/
/* implicit optional callingNumber tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* implicit choice presented number screened tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* implicit choice presentationAllowedAddress tag */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
/* type of public party number = subscriber number */
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 4);
j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, c->callernum, strlen(c->callernum));
if (j < 0)
return -1;
i += j;
ASN1_FIXUP(compstk, compsp, buffer, i);
/* Screeening Indicator network provided */
ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3);
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
/**/
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL);
if (res) {
pri_message(pri, "Could not queue ADPU in facility message\n");
return -1;
}
/* Remember that if we queue a facility IE for a facility message we
* have to explicitly send the facility message ourselves */
res = q931_facility(c->pri, c);
if (res) {
pri_message(pri, "Could not schedule facility message for call %d\n", c->cr);
return -1;
}
return 0;
}
/* End QSIG CC-CallRerouting */
static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_ie *ie)
{
int res;
@@ -1215,7 +1407,7 @@ static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_
return 0;
}
/* AFN-PR */
extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
{
/* Did all the tests to see if we're on the same PRI and
* are on a compatible switchtype */
@@ -1233,7 +1425,6 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
/* Channel 1 */
buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
/* Interpretation component */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
ASN1_PUSH(compstk, compsp, comp);
@@ -1241,6 +1432,7 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
ASN1_FIXUP(compstk, compsp, buffer, i);
/* Interpretation component */
ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2); /* reject - to get feedback from QSIG switch */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
@@ -1255,15 +1447,22 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
buffer[i++] = (0x0a);
buffer[i++] = (0x01);
buffer[i++] = (0x00);
buffer[i++] = (0x81);
buffer[i++] = (0x00);
buffer[i++] = (0x0a);
buffer[i++] = (0x01);
buffer[i++] = (0x01);
buffer[i++] = (0x0a);/* Enumeration endDesignation */
buffer[i++] = (0x01);/* Len */
buffer[i++] = (0x00);/* primaryEnd */
buffer[i++] = (0x81);/* redirectionNumber = presentationRestricted */
buffer[i++] = (0x00);/* Len */
buffer[i++] = (0x0a);/* Enumeration callStatus */
buffer[i++] = (0x01);/* Len */
buffer[i++] = (0x01);/* alerting */
/*
* Where does this element come from? It is not in Q.SIG ECMA-178.
* We send this but we will not accept it.
* This seems to be a cut and paste error from eect_initiate_transfer().
*/
ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer, i, call_reference);
ASN1_FIXUP(compstk, compsp, buffer, i);
ASN1_FIXUP(compstk, compsp, buffer, i);
@@ -1288,7 +1487,6 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
compsp = 0;
buffer2[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
/* Interpretation component */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer2, i);
ASN1_PUSH(compstk, compsp, comp);
@@ -1296,6 +1494,7 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer2, i, 0);
ASN1_FIXUP(compstk, compsp, buffer2, i);
/* Interpretation component */
ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer2, i, 2); /* reject */
ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer2, i);
@@ -1310,15 +1509,22 @@ extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2
ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer2, i);
ASN1_PUSH(compstk, compsp, comp);
buffer2[i++] = (0x0a);
buffer2[i++] = (0x01);
buffer2[i++] = (0x01);
buffer2[i++] = (0x81);
buffer2[i++] = (0x00);
buffer2[i++] = (0x0a);
buffer2[i++] = (0x01);
buffer2[i++] = (0x01);
buffer2[i++] = (0x0a);/* Enumeration endDesignation */
buffer2[i++] = (0x01);/* Len */
buffer2[i++] = (0x01);/* secondaryEnd */
buffer2[i++] = (0x81);/* redirectionNumber = presentationRestricted */
buffer2[i++] = (0x00);/* Len */
buffer2[i++] = (0x0a);/* Enumeration callStatus */
buffer2[i++] = (0x01);/* Len */
buffer2[i++] = (0x01);/* alerting */
/*
* Where does this element come from? It is not in Q.SIG ECMA-178.
* We send this but we will not accept it.
* This seems to be a cut and paste error from eect_initiate_transfer().
*/
ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer2, i, call_reference);
ASN1_FIXUP(compstk, compsp, buffer2, i);
ASN1_FIXUP(compstk, compsp, buffer2, i);
@@ -1548,6 +1754,47 @@ static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long cha
}
/* End AOC */
static int rose_calling_name_decode(struct pri *pri, q931_call *call, struct rose_component *choice, int len)
{
int i = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = choice->data;
int characterSet = 1;
switch (choice->type) {
case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:
memcpy(call->callername, choice->data, choice->len);
call->callername[choice->len] = 0;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Received simple calling name '%s'\n", call->callername);
return 0;
case ROSE_NAME_PRESENTATION_ALLOWED_EXTENDED:
do {
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_OCTETSTRING, "Don't know what to do if nameData is of type 0x%x\n");
memcpy(call->callername, comp->data, comp->len);
call->callername[comp->len] = 0;
NEXT_COMPONENT(comp, i);
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if CharacterSet is of type 0x%x\n");
ASN1_GET_INTEGER(comp, characterSet);
}
while (0);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Received extended calling name '%s', characterset %d\n", call->callername, characterSet);
return 0;
case ROSE_NAME_PRESENTATION_RESTRICTED_SIMPLE:
case ROSE_NAME_PRESENTATION_RESTRICTED_EXTENDED:
case ROSE_NAME_PRESENTATION_RESTRICTED_NULL:
case ROSE_NAME_NOT_AVAIL:
default:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "Do not handle argument of type 0x%X\n", choice->type);
return -1;
}
}
/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */
static int rose_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
@@ -2034,7 +2281,7 @@ int rose_reject_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned c
return 0;
} else {
pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
pri_message(pri, "Unable to handle reject on switchtype %d!\n", pri->switchtype);
return -1;
}
@@ -2097,8 +2344,7 @@ int rose_return_error_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsi
return 0;
} else {
pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
return -1;
pri_message(pri, "Unable to handle return error on switchtype %d!\n", pri->switchtype);
}
} while(0);
@@ -2158,6 +2404,12 @@ int rose_return_result_decode(struct pri *pri, q931_call *call, q931_ie *ie, uns
pri_message(pri, "Could not parse invoke of type 0x%x!\n", invokeidvalue);
return -1;
}
} else if (pri->switchtype == PRI_SWITCH_QSIG) {
switch (invokeidvalue) {
case 0x13:
if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Successfully completed QSIG CF callRerouting!\n");
return 0;
}
} else {
pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
return -1;
@@ -2209,19 +2461,7 @@ int rose_invoke_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned c
case SS_CNID_CALLINGNAME:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Handle Name display operation\n");
switch (comp->type) {
case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:
memcpy(call->callername, comp->data, comp->len);
call->callername[comp->len] = 0;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Received caller name '%s'\n", call->callername);
return 0;
default:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "Do not handle argument of type 0x%X\n", comp->type);
return -1;
}
break;
return rose_calling_name_decode(pri, call, comp, len-i);
case ROSE_CALL_TRANSFER_IDENTIFY:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferIdentify - not handled!\n", operation_tag);
@@ -2267,8 +2507,10 @@ int rose_invoke_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned c
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_DIVERTING_LEG_INFORMATION2:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Handle DivertingLegInformation2\n");
if (pri->debug & PRI_DEBUG_APDU) {
pri_message(pri, "ROSE %i: Handle CallingName\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
}
return rose_diverting_leg_information2_decode(pri, call, comp, len-i);
case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE:
if (pri->debug & PRI_DEBUG_APDU) {

View File

@@ -41,7 +41,10 @@
/* Argument values */
#define ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE 0x80
#define ROSE_NAME_PRESENTATION_RESTRICTED_NULL 0x87
#define ROSE_NAME_NOT_AVAIL 0x84
#define ROSE_NAME_PRESENTATION_ALLOWED_EXTENDED 0xA1
#define ROSE_NAME_PRESENTATION_RESTRICTED_SIMPLE 0xA2
#define ROSE_NAME_PRESENTATION_RESTRICTED_EXTENDED 0xA3
#define ROSE_NAME_NOT_AVAIL 0x84
/* Component types */
#define COMP_TYPE_INTERPRETATION 0x8B
@@ -306,8 +309,10 @@ int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason);
/* starts a QSIG Path Replacement */
extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
/* Use this function to queue a facility-IE born APDU onto a call
* call is the call to use, messagetype is any one of the Q931 messages,

View File

@@ -114,6 +114,9 @@ struct pri {
/* do we do overlap dialing */
int overlapdial;
/* do not skip channel 16 */
int chan_mapping_logical;
#ifdef LIBPRI_COUNTERS
/* q921/q931 packet counters */
unsigned int q921_txcount;

View File

@@ -186,7 +186,7 @@ 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);
extern void q921_reset(struct pri *pri);
extern void q921_reset(struct pri *pri, int reset_iqueue);
extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);

View File

@@ -256,6 +256,8 @@ extern int q931_receive(struct pri *pri, q931_h *h, int len);
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_call_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause);
extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);

325
q921.c
View File

@@ -56,6 +56,7 @@
} while(0)
static void reschedule_t203(struct pri *pri);
static void reschedule_t200(struct pri *pri);
static void q921_restart(struct pri *pri, int now);
static void q921_tei_release_and_reacquire(struct pri *master);
@@ -97,7 +98,6 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
pri_error(pri, "Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
return -1;
}
reschedule_t203(pri);
return 0;
}
@@ -238,21 +238,6 @@ static int q921_ack_packet(struct pri *pri, int num)
pri->retrans = 0;
/* Decrement window size */
pri->windowlen--;
/* Search for something to send */
f = pri->txqueue;
while(f) {
if (!f->transmitted) {
/* Send it now... */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Finally transmitting %d, since window opened up\n", f->h.n_s);
f->transmitted++;
pri->windowlen++;
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
break;
}
f = f->next;
}
return 1;
}
prev = f;
@@ -265,18 +250,45 @@ static void t203_expire(void *);
static void t200_expire(void *);
static pri_event *q921_dchannel_down(struct pri *pri);
static void reschedule_t200(struct pri *pri)
{
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Restarting T200 timer\n");
if (pri->t200_timer)
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
}
static void reschedule_t203(struct pri *pri)
{
if (pri->t203_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Restarting T203 timer\n");
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Restarting T203 counter\n");
/* Nothing to transmit, start the T203 counter instead */
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
static void q921_send_queued_iframes(struct pri *pri)
{
struct q921_frame *f;
f = pri->txqueue;
while(f && (pri->windowlen < pri->window)) {
if (!f->transmitted) {
/* Send it now... */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Finally transmitting %d, since window opened up (%d)\n", f->h.n_s, pri->windowlen);
f->transmitted++;
pri->windowlen++;
f->h.n_r = pri->v_r;
f->h.p_f = 0;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
}
f = f->next;
}
}
static pri_event *q921_ack_rx(struct pri *pri, int ack)
static pri_event *q921_ack_rx(struct pri *pri, int ack, int send_untransmitted_frames)
{
int x;
int cnt=0;
@@ -300,8 +312,10 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
if (pri->debug & PRI_DEBUG_Q921_DUMP)
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->t200_timer) {
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
}
if (pri->t203_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
@@ -311,10 +325,14 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
}
if (pri->txqueue) {
/* Something left to transmit, Start the T200 counter again if we stopped it */
if (!pri->busy && send_untransmitted_frames) {
pri->retrans = 0;
/* Search for something to send */
q921_send_queued_iframes(pri);
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue->h.n_s);
if (!pri->t200_timer)
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
pri_message(pri, "-- Waiting for acknowledge, restarting T200 counter\n");
reschedule_t200(pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Nothing left, starting T203 counter\n");
@@ -384,20 +402,16 @@ static void q921_rr(struct pri *pri, int pbit, int cmd) {
static void t200_expire(void *vpri)
{
struct pri *pri = vpri;
q921_frame *f, *lastframe=NULL;
if (pri->txqueue) {
/* Retransmit first packet in the queue, setting the poll bit */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- T200 counter expired, What to do...\n");
/* Force Poll bit */
pri->txqueue->h.p_f = 1;
/* Update nr */
pri->txqueue->h.n_r = pri->v_r;
pri->v_na = pri->v_r;
pri->solicitfbit = 1;
pri->retrans++;
/* Up to three retransmissions */
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
pri->retrans++;
/* Reschedule t200_timer */
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
@@ -406,7 +420,19 @@ static void t200_expire(void *vpri)
else {
if (!pri->txqueue->transmitted)
pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
/*Actually we need to retransmit the last transmitted packet, setting the poll bit */
for (f=pri->txqueue; f; f = f->next) {
if (f->transmitted)
lastframe = f;
}
if (lastframe) {
/* Force Poll bit */
lastframe->h.p_f = 1;
/* Update nr */
lastframe->h.n_r = pri->v_r;
pri->v_na = pri->v_r;
q921_transmit(pri, (q921_h *)&lastframe->h, lastframe->len);
}
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);
@@ -418,15 +444,20 @@ static void t200_expire(void *vpri)
pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n",DBGINFO);
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
if (pri->bri && pri->master) {
q921_tei_release_and_reacquire(pri->master);
return;
} else {
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
}
}
} else if (pri->solicitfbit) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Retrying poll with f-bit\n");
pri->retrans++;
if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
pri->retrans++;
pri->solicitfbit = 1;
q921_rr(pri, 1, 1);
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
@@ -490,11 +521,9 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
pri->txqueue = f;
/* Immediately transmit unless we're in a recovery state, or the window
size is too big */
if (!pri->retrans && !pri->busy) {
if ((pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) && (!pri->retrans && !pri->busy)) {
if (pri->windowlen < pri->window) {
pri->windowlen++;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
f->transmitted++;
q921_send_queued_iframes(pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n",
@@ -507,14 +536,14 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = 0;
}
if (!pri->t200_timer) {
/* Check this so that we don't try to send frames while multi frame mode is down */
if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "Starting T_200 timer\n");
pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
} else
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
reschedule_t200(pri);
}
} else {
pri_error(pri, "!! Out of memory for Q.921 transmit\n");
return -1;
@@ -540,25 +569,26 @@ static void t203_expire(void *vpri)
pri->t203_timer = 0;
}
}
static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len)
{
int res;
pri_event *ev;
pri->solicitfbit = 0;
/* Make sure this is a valid packet */
if (i->n_s == pri->v_r) {
/* Increment next expected I-frame */
Q921_INC(pri->v_r);
/* Handle their ACK */
pri->sentrej = 0;
ev = q921_ack_rx(pri, i->n_r);
ev = q921_ack_rx(pri, i->n_r, 1);
if (ev)
return ev;
if (i->p_f) {
/* If the Poll/Final bit is set, immediate send the RR */
q921_rr(pri, 1, 0);
} else if (pri->busy) {
q921_rr(pri, 0, 0);
} else if (pri->busy || pri->retrans) {
q921_rr(pri, 0, 0);
}
/* Receive Q.931 data */
res = q931_receive(pri, (q931_h *)i->data, len - 4);
@@ -622,6 +652,7 @@ void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx)
direction_tag,
h->h.tei,
h->h.ea2);
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
case 0:
case 2:
@@ -712,13 +743,54 @@ void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx)
len - 3);
break;
};
if ((h->u.ft == 3) && (h->u.m3 == 0) && (h->u.m2 == 0) && (h->u.data[0] == 0x0f)) {
int ri;
int tei;
ri = (h->u.data[1] << 8) | h->u.data[2];
tei = (h->u.data[4] >> 1);
/* TEI assignment related */
switch (h->u.data[3]) {
case Q921_TEI_IDENTITY_REQUEST:
type = "TEI Identity Request";
break;
case Q921_TEI_IDENTITY_ASSIGNED:
type = "TEI Identity Assigned";
break;
case Q921_TEI_IDENTITY_CHECK_REQUEST:
type = "TEI Identity Check Request";
break;
case Q921_TEI_IDENTITY_REMOVE:
type = "TEI Identity Remove";
break;
case Q921_TEI_IDENTITY_DENIED:
type = "TEI Identity Denied";
break;
case Q921_TEI_IDENTITY_CHECK_RESPONSE:
type = "TEI Identity Check Response";
break;
case Q921_TEI_IDENTITY_VERIFY:
type = "TEI Identity Verify";
break;
default:
type = "Unknown";
break;
}
pri_message(pri, "%c MDL Message: %s (%d)\n", direction_tag, type, h->u.data[3]);
pri_message(pri, "%c RI: %d\n", direction_tag, ri);
pri_message(pri, "%c Ai: %d E:%d\n", direction_tag, (h->u.data[4] >> 1) & 0x7f, h->u.data[4] & 1);
}
}
static pri_event *q921_dchannel_up(struct pri *pri)
{
/* Reset counters, etc */
q921_reset(pri);
if (pri->tei == Q921_TEI_PRI) {
q921_reset(pri, 1);
} else {
q921_reset(pri, 0);
}
/* Stop any SABME retransmissions */
if (pri->sabme_timer) {
pri_schedule_del(pri, pri->sabme_timer);
@@ -739,6 +811,8 @@ static pri_event *q921_dchannel_up(struct pri *pri)
/* Notify Layer 3 */
q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
q921_send_queued_iframes(pri);
/* Report event that D-Channel is now up */
pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
return &pri->ev;
@@ -747,7 +821,7 @@ static pri_event *q921_dchannel_up(struct pri *pri)
static pri_event *q921_dchannel_down(struct pri *pri)
{
/* Reset counters, reset sabme timer etc */
q921_reset(pri);
q921_reset(pri, 1);
/* Notify Layer 3 */
q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
@@ -757,10 +831,12 @@ static pri_event *q921_dchannel_down(struct pri *pri)
return &pri->ev;
}
void q921_reset(struct pri *pri)
void q921_reset(struct pri *pri, int reset_iqueue)
{
/* Having gotten a SABME we MUST reset our entire state */
pri->v_s = 0;
if (reset_iqueue)
pri->v_s = 0;
pri->v_a = 0;
pri->v_r = 0;
pri->v_na = 0;
@@ -785,7 +861,8 @@ void q921_reset(struct pri *pri)
pri->sentrej = 0;
/* Discard anything waiting to go out */
q921_discard_retransmissions(pri);
if (reset_iqueue)
q921_discard_retransmissions(pri);
}
static void q921_tei_release_and_reacquire(struct pri *master)
@@ -883,6 +960,18 @@ static pri_event *q921_receive_MDL(struct pri *pri, q921_u *h, int len)
return NULL; /* Do we need to return something??? */
}
static int is_command(struct pri *pri, q921_h *h)
{
int command =0;
int c_r = h->s.h.c_r;
if ((pri->localtype == PRI_NETWORK && c_r == 0) ||
(pri->localtype == PRI_CPE && c_r == 1))
command = 1;
return( command );
}
static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
{
q921_frame *f;
@@ -917,74 +1006,98 @@ static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
/* Receiver Ready */
pri->busy = 0;
/* Acknowledge frames as necessary */
ev = q921_ack_rx(pri, h->s.n_r);
ev = q921_ack_rx(pri, h->s.n_r, 1);
if (ev)
return ev;
if (is_command(pri, h))
pri->solicitfbit = 0;
if (h->s.p_f) {
/* If it's a p/f one then send back a RR in return with the p/f bit set */
if (pri->solicitfbit) {
if (!is_command(pri, h)) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Got RR response to our frame\n");
pri->retrans = 0;
} else {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
q921_rr(pri, 1, 0);
}
pri->solicitfbit = 0;
}
break;
case 1:
/* Receiver not ready */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got receiver not ready\n");
if(h->s.p_f) {
/* Send RR if poll bit set */
q921_rr(pri, h->s.p_f, 0);
}
pri->busy = 1;
ev = q921_ack_rx(pri, h->s.n_r, 0);
if (ev)
return ev;
if (h->s.p_f && is_command(pri, h))
q921_rr(pri, 1, 0);
pri->solicitfbit = 1;
pri->retrans = 0;
if (pri->t203_timer) {
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "Stopping T_203 timer\n");
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = 0;
}
if (pri->debug & PRI_DEBUG_Q921_DUMP)
pri_message(pri, "Restarting T_200 timer\n");
reschedule_t200(pri);
break;
case 2:
/* Just retransmit */
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message(pri, "-- Got reject requesting packet %d... Retransmitting.\n", h->s.n_r);
if (h->s.p_f) {
/* If it has the poll bit set, send an appropriate supervisory response */
q921_rr(pri, 1, 0);
}
sendnow = 0;
/* Resend the proper I-frame */
for(f=pri->txqueue;f;f=f->next) {
if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
/* Matches the request, or follows in our window, and has
already been transmitted. */
sendnow = 1;
pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
}
}
if (!sendnow) {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
}
} else {
/* Hrm, we have nothing to send, but have been REJ'd. Reset v_a, v_s, etc */
pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
pri->v_a = h->s.n_r;
pri->v_s = h->s.n_r;
/* Reset t200 timer if it was somehow going */
if (pri->t200_timer) {
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
/* Reset and restart t203 timer */
if (pri->t203_timer)
pri_schedule_del(pri, pri->t203_timer);
pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
}
}
if (pri->busy && !is_command(pri, h))
pri->solicitfbit = 0;
pri->busy = 0;
if (is_command(pri, h) && h->s.p_f)
q921_rr(pri, 1, 0);
q921_ack_rx(pri, h->s.n_r, 0);
/*Resend only if we are in the Multiple Frame Established state or when
we are in the Time Recovery state and received responce with bit F=1*/
if ((pri->solicitfbit == 0) || (pri->solicitfbit && !is_command(pri, h) && h->s.p_f)) {
pri->solicitfbit = 0;
pri->retrans = 0;
sendnow = 0;
/* Resend I-frames starting from frame where f->h.n_s == h->s.n_r */
for (f = pri->txqueue; f && (f->h.n_s != h->s.n_r); f = f->next);
while (f) {
sendnow = 1;
if (f->transmitted || (!f->transmitted && (pri->windowlen < pri->window))) {
if (pri->debug & PRI_DEBUG_Q921_STATE)
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;
f->h.p_f = 0;
if (!f->transmitted && (pri->windowlen < pri->window))
pri->windowlen++;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
}
f = f->next;
}
if (!sendnow) {
if (pri->txqueue) {
/* This should never happen */
if (!h->s.p_f || h->s.n_r) {
pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
}
} else {
/* Hrm, we have nothing to send, but have been REJ'd. Reset v_a, v_s, etc */
pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
pri->v_a = h->s.n_r;
pri->v_s = h->s.n_r;
}
}
/* Reset t200 timer if it was somehow going */
if (pri->t200_timer) {
pri_schedule_del(pri, pri->t200_timer);
pri->t200_timer = 0;
}
/* Reset and restart t203 timer */
reschedule_t203(pri);
}
break;
default:
pri_error(pri, "!! XXX Unknown Supervisory frame ss=0x%02x,pf=%02xnr=%02x vs=%02x, va=%02x XXX\n", h->s.ss, h->s.p_f, h->s.n_r,
@@ -1152,14 +1265,14 @@ static void q921_restart(struct pri *pri, int now)
return;
}
/* Reset our interface */
q921_reset(pri);
q921_reset(pri, 1);
/* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
q921_send_sabme(pri, now);
}
void q921_start(struct pri *pri, int isCPE)
{
q921_reset(pri);
q921_reset(pri, 1);
if ((pri->sapi == Q921_SAPI_LAYER2_MANAGEMENT) && (pri->tei == Q921_TEI_GROUP)) {
pri->q921_state = Q921_DOWN;
if (isCPE)

46
q931.c
View File

@@ -345,6 +345,8 @@ static FUNC_RECV(receive_channel_id)
pos++;
/* Only expect a particular channel */
call->channelno = ie->data[pos] & 0x7f;
if (pri->chan_mapping_logical && call->channelno > 15)
call->channelno++;
return 0;
}
} else
@@ -400,7 +402,10 @@ static FUNC_SEND(transmit_channel_id)
ie->data[pos++] = 0x83;
if (call->channelno > -1) {
/* Channel number specified */
ie->data[pos++] = 0x80 | call->channelno;
if (pri->chan_mapping_logical && call->channelno > 16)
ie->data[pos++] = 0x80 | (call->channelno - 1);
else
ie->data[pos++] = 0x80 | call->channelno;
return pos + 2;
}
/* We have to send a channel map */
@@ -820,6 +825,12 @@ static FUNC_SEND(transmit_bearer_capability)
/* Apparently EuroISDN switches don't seem to like user layer 2/3 */
return 4;
}
if ((tc & PRI_TRANS_CAP_DIGITAL) && (call->transmoderate == TRANS_MODE_64_CIRCUIT)) {
/* Unrestricted digital 64k data calls don't use user layer 2/3 */
return 4;
}
if (call->transmoderate != TRANS_MODE_PACKET) {
/* If you have an AT&T 4ESS, you don't send any more info */
if ((pri->switchtype != PRI_SWITCH_ATT4ESS) && (call->userl1 > -1)) {
@@ -2731,6 +2742,8 @@ int q931_notify(struct pri *pri, q931_call *c, int channel, int info)
#ifdef ALERTING_NO_PROGRESS
static int call_progress_ies[] = { -1 };
#else
static int call_progress_with_cause_ies[] = { Q931_PROGRESS_INDICATOR, Q931_CAUSE, -1 };
static int call_progress_ies[] = { Q931_PROGRESS_INDICATOR, -1 };
#endif
@@ -2742,6 +2755,7 @@ int q931_call_progress(struct pri *pri, q931_call *c, int channel, int info)
channel &= 0xff;
c->channelno = channel;
}
if (info) {
c->progloc = LOC_PRIV_NET_LOCAL_USER;
c->progcode = CODE_CCITT;
@@ -2751,10 +2765,38 @@ int q931_call_progress(struct pri *pri, q931_call *c, int channel, int info)
pri_error(pri, "XXX Progress message requested but no information is provided\n");
c->progressmask = 0;
}
c->alive = 1;
return send_message(pri, c, Q931_PROGRESS, call_progress_ies);
}
int q931_call_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause)
{
if (channel) {
c->ds1no = (channel & 0xff00) >> 8;
c->ds1explicit = (channel & 0x10000) >> 16;
channel &= 0xff;
c->channelno = channel;
}
if (info) {
c->progloc = LOC_PRIV_NET_LOCAL_USER;
c->progcode = CODE_CCITT;
c->progressmask = PRI_PROG_INBAND_AVAILABLE;
} else {
/* PI is mandatory IE for PROGRESS message - Q.931 3.1.8 */
pri_error(pri, "XXX Progress message requested but no information is provided\n");
c->progressmask = 0;
}
c->cause = cause;
c->causecode = CODE_CCITT;
c->causeloc = LOC_PRIV_NET_LOCAL_USER;
c->alive = 1;
return send_message(pri, c, Q931_PROGRESS, call_progress_with_cause_ies);
}
#ifdef ALERTING_NO_PROGRESS
static int call_proceeding_ies[] = { Q931_CHANNEL_IDENT, -1 };
#else
@@ -2949,7 +2991,7 @@ static int restart_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 };
int q931_restart(struct pri *pri, int channel)
{
struct q931_call *c;
c = q931_getcall(pri, 0 | 0x8000, 0);
c = q931_getcall(pri, 0 | 0x8000, 1);
if (!c)
return -1;
if (!channel)