Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
585c016da8 | ||
|
|
f86ab05045 | ||
|
|
07b3f1dc45 | ||
|
|
3d5f9e762a | ||
|
|
d808143f8f | ||
|
|
14c3616e02 | ||
|
|
bfcab2eabe | ||
|
|
ca0fc1a99d | ||
|
|
d933b7e7e6 | ||
|
|
e42108aaae | ||
|
|
7babaeb2fe | ||
|
|
5ff4710e77 | ||
|
|
9a7686d792 | ||
|
|
ba4d759752 | ||
|
|
d5d69dddac | ||
|
|
68a107a3e3 | ||
|
|
307264f7c6 | ||
|
|
2ec071bae6 | ||
|
|
d4354b4873 | ||
|
|
9d9412e681 | ||
|
|
a09da00b0a | ||
|
|
748c69e160 | ||
|
|
6443238ed0 | ||
|
|
f80fa82b33 | ||
|
|
3995397fa3 | ||
|
|
cec71a81e5 | ||
|
|
7dd6494c61 | ||
|
|
79fbecc5ae | ||
|
|
4d3bb14731 | ||
|
|
14f04072c8 | ||
|
|
46df6d2cd4 | ||
|
|
b9397c7541 | ||
|
|
04d911112d | ||
|
|
b698032e04 | ||
|
|
62d35faf6b | ||
|
|
d305dbc609 | ||
|
|
80c8c46b89 | ||
|
|
6a121d4c74 | ||
|
|
44ad020fe8 | ||
|
|
e23ea9568c | ||
|
|
c7c670aa85 | ||
|
|
618acf9d53 | ||
|
|
9f39144986 | ||
|
|
16f2f02ce8 | ||
|
|
a2dcb6adba | ||
|
|
a78ee730c9 | ||
|
|
6cb01561eb | ||
|
|
5537dbec1d | ||
|
|
0c210c19fa | ||
|
|
92c277dae5 | ||
|
|
28e7e1cdfe | ||
|
|
296c64df23 | ||
|
|
ab1580de67 | ||
|
|
3a9af361fd | ||
|
|
175c1e470f | ||
|
|
18ea19900c | ||
|
|
4d19486781 | ||
|
|
599128a65a | ||
|
|
c8de5d057b | ||
|
|
25b2496b0f | ||
|
|
d9af5b25ce | ||
|
|
c3074dafc1 | ||
|
|
6d9c1cb0d9 | ||
|
|
6d5aeb7cdd | ||
|
|
503ef0531a | ||
|
|
e7c9ecb1b2 | ||
|
|
61f7a372d9 | ||
|
|
97f33e3286 | ||
|
|
3908bf2e48 | ||
|
|
176f0bf6cd | ||
|
|
d32e70d473 | ||
|
|
69fecfd30a | ||
|
|
2ada419b08 | ||
|
|
dcd62e467f | ||
|
|
926cc924d2 | ||
|
|
13fbd05e0b | ||
|
|
f04f345113 | ||
|
|
27a5c7afb6 | ||
|
|
01e637393e | ||
|
|
4f0b3f3109 | ||
|
|
24cc37a839 | ||
|
|
562e1fb7ca | ||
|
|
c5cdc66b72 | ||
|
|
2eaca806b9 | ||
|
|
7092459702 | ||
|
|
64fd25fcac | ||
|
|
16304b6a65 | ||
|
|
ea4d305ffb | ||
|
|
3a1739883b | ||
|
|
47830a68aa | ||
|
|
2176bd7fa3 | ||
|
|
3c12135659 | ||
|
|
c69e4780ef | ||
|
|
e7b64b16da | ||
|
|
39f7f72d8f | ||
|
|
5484712af0 | ||
|
|
a5b9b792ea | ||
|
|
c430cba165 | ||
|
|
ac40946c11 | ||
|
|
b19c0b0a04 | ||
|
|
ba45095c5a | ||
|
|
18fa4716a5 | ||
|
|
f9d5aa3c3a | ||
|
|
88551af7ef | ||
|
|
29ded17c0b | ||
|
|
bbaeec9513 | ||
|
|
48fc219865 | ||
|
|
9ecdbed001 | ||
|
|
3d91cd5e30 | ||
|
|
a30eeee9a8 |
711
ChangeLog
711
ChangeLog
@@ -1,3 +1,714 @@
|
||||
2010-05-20 Russell Bryant <russell@digium.com>
|
||||
|
||||
* libpri 1.4.11 released.
|
||||
|
||||
2010-05-19 21:50 +0000 [r1703] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: T309 should not do anything with the global call
|
||||
reference call record.
|
||||
|
||||
2010-05-19 21:30 +0000 [r1702] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: It's amazing what a tiny bug in the Q.921 SDL diagram can
|
||||
do to cause trouble.... Fix issue where V_R was not reset and N_R
|
||||
was consequentially transmitted incorrectly. Particularly in
|
||||
layer 2 initiated re-establishments.
|
||||
|
||||
2010-05-11 22:14 +0000 [r1688] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, q931.c, libpri.h: Dialing an invalid
|
||||
extension causes incomplete hangup sequence. Revision -r1489
|
||||
corrected a deviation from Q.931 Section 5.3.2. However, this
|
||||
resulted in an unexpected behaviour change to the upper layer
|
||||
(Asterisk). This change restores the legacy hangup behaviour if
|
||||
the new API call is not used. Use pri_hangup_fix_enable() to
|
||||
follow Q.931 Section 5.3.2 call hangup better. (closes issue
|
||||
#17104) Reported by: shawkris Tested by: rmudgett
|
||||
|
||||
2010-04-26 19:54 +0000 [r1664-1675] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Simplified some protocol discriminator handling code.
|
||||
|
||||
* q931.c: Garbage on the end of Q.931 messages causing calls to
|
||||
fail to connect. The DAHDI driver had a bug where an extra byte
|
||||
appeared on the end of Q.931 messages. This garbage byte caused
|
||||
the message to be discarded with the diagnostic "XXX Message
|
||||
longer than it should be?? XXX". The Q.931 message will no longer
|
||||
be discarded if there were earlier ie's in the message. This
|
||||
patch also addresses the potential problem of reading beyond the
|
||||
buffer when trying to parse the garbage data. Thanks to roeften
|
||||
for the base patch. (closes issue #14378) Reported by: timking
|
||||
|
||||
* q921.c: Avoid using a cast.
|
||||
|
||||
* q931.c: Cleanup some pri debug output line presentation.
|
||||
|
||||
2010-04-19 22:40 +0000 [r1625-1630] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_internal.h, pri_q931.h, q931.c, pridump.c: PTMP NT mode call
|
||||
reference value ambiguity. Since the TE side can pick CR values
|
||||
independently, the TE CR needs to be qualified by TEI to
|
||||
distinguish CR values from other devices. Without doing this,
|
||||
multiple phones on the BRI line will have intermittent call
|
||||
failures. JIRA LIBPRI-30 Also eliminated some wierdness in
|
||||
q931_status() and several places where it is called.
|
||||
|
||||
* q921.c: Fix potential crash when pridump.c calls q921_dump() with
|
||||
NULL pri ptr.
|
||||
|
||||
2010-04-15 18:43 +0000 [r1596] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h: Make some internal routines available to
|
||||
other libpri components.
|
||||
|
||||
2010-04-09 21:43 +0000 [r1577] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Only one PROCEEDING message per call please.
|
||||
|
||||
2010-03-18 15:50 +0000 [r1534-1547] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Move a comment closer to where it has relevance.
|
||||
|
||||
* pri.c, pri_internal.h, q921.c, q931.c, pri_facility.c:
|
||||
Miscellaneous simple reorganization. 1) Make PRI_MASTER() no
|
||||
longer check for a NULL parameter. It is the caller's
|
||||
responsibility. Not many callers could have passed a NULL without
|
||||
crashing before or after anyway. 2) Replace calls to
|
||||
q931_is_ptmp() with PTMP_MODE(). They were equivalent. 3) Made
|
||||
the following boolean config options bit fields: sendfacility,
|
||||
overlapdial, chan_mapping_logical, and service_message_support.
|
||||
|
||||
2010-03-02 23:47 +0000 [r1511] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, q921.c: Restore ability to change the
|
||||
Q.921 K value. The Q.921 rewrite only used value of PRI_TIMER_K
|
||||
right after it was set to the default. The Q.921 window size was
|
||||
thus no longer alterable by the user. (closes issue #16909)
|
||||
Reported by: alecdavis Patches: pritimer.libpri.diff.txt uploaded
|
||||
by alecdavis (license 585) Tested by: alecdavis
|
||||
|
||||
2010-02-11 21:47 +0000 [r1488-1489] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Must send DISCONNECT if we have sent a response to a
|
||||
SETUP message. Q.931 Section 5.3.2 a) says we send a
|
||||
RELEASE_COMPLETE to reject a call SETUP if we have not already
|
||||
sent a message in response to the SETUP message.
|
||||
|
||||
* pri.c, libpri.h: Minor comment changes.
|
||||
|
||||
2010-02-11 17:35 +0000 [r1482] Wendell Thompson <wthompson@digium.com>
|
||||
|
||||
* Makefile: Added CPUARCH option for selecting a 32-bit build from
|
||||
the command line.
|
||||
|
||||
2010-02-08 23:29 +0000 [r1470-1476] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: Revert useless check of pri->t200_timer value, since
|
||||
scheduler routines check the value anyways.
|
||||
|
||||
* q921.c: Make sure we set the l3initiated flag when PTP links are
|
||||
attempted to be re-established
|
||||
|
||||
2010-02-05 23:34 +0000 [r1464] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c: pri_restart() is no longer needed since the Q.921 rewrite.
|
||||
Don't output error message for a deprecated function.
|
||||
|
||||
2010-01-29 21:55 +0000 [r1457] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: Sense of statement was inverted from what it should have
|
||||
been. Might have caused false T200 operation on reception of
|
||||
I-frames.
|
||||
|
||||
2010-01-29 19:32 +0000 [r1451] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q921.c: Only set eres if there actually is an event to pass up.
|
||||
(issue 16713)
|
||||
|
||||
2010-01-29 17:27 +0000 [r1445] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: Fix bug in which an event was lost if an I-frame was
|
||||
received during a timer recovery state (related to #16713)
|
||||
|
||||
2010-01-26 21:04 +0000 [r1439] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q921.c: Don't be so noisy when D channel is down.
|
||||
|
||||
2010-01-19 21:53 +0000 [r1426] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q921.c, q931.c: Fix TE PTMP side sending FACILITY messages on the
|
||||
dummy call reference. Only the NT PTMP side can send Q.931
|
||||
broadcast messages. Also removed an inaccurate comment in Q.921
|
||||
and made q921_mdl_handle_error_callback() call the correct struct
|
||||
pri free function.
|
||||
|
||||
2010-01-15 18:28 +0000 [r1414] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q921.c, q931.c: Make some debugging messages conditional and some
|
||||
minor reformating changes.
|
||||
|
||||
2010-01-13 19:37 +0000 [r1406] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, pri_q921.h, Makefile, pri_q931.h, q921.c,
|
||||
q931.c: Merge of Q.921 rewrite branch for wider testing.
|
||||
|
||||
2009-12-09 20:59 +0000 [r1374] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Extracted q931_fill_ring_event() from
|
||||
post_handle_q931_message(). Done so it is easier to see what was
|
||||
done in ccbs branch.
|
||||
|
||||
2009-11-21 02:40 +0000 [r1345-1351] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h: Fix debug output so built up output lines
|
||||
are readable again. A recent change to Asterisk put the span
|
||||
number at the begining of each line. This is a good thing if you
|
||||
need to debug multiple spans or forget which span you are
|
||||
debugging. Unfortunately, any pri_message() output that is not a
|
||||
complete line is messed up. The pri_message() function now will
|
||||
accumulate line output until a '\n' is seen on the end.
|
||||
|
||||
* pri_internal.h, q931.c, pri_facility.c: Delay processing of
|
||||
facility ie's after all other ie's are processed. * Some ROSE
|
||||
message processing depends on the presence of other ies. The
|
||||
DivertingLegInformation1, and 3 messages will be used as the
|
||||
default connected line number if the connected number ie is not
|
||||
present. The redirecting number ie is used as a default to the
|
||||
redirecting number in the DivertingLegInformation2 message if the
|
||||
ROSE message does not contain it and the redirecting number ie is
|
||||
present. * Some ROSE message processing depends upon other ie
|
||||
values. The StatusRequest, CCBS-T-Call, and CcRingout messages
|
||||
collectively need the BC, HLC, LLC, called number, called
|
||||
subaddress, calling number, and calling subaddress ie information
|
||||
to be available.
|
||||
|
||||
2009-11-18 00:36 +0000 [r1331] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Merged revision 1328 from
|
||||
https://origsvn.digium.com/svn/libpri/team/mattf/libpri-1.4-q921-rewrite
|
||||
.......... r1328 | mattf | 2009-11-17 15:16:11 -0600 (Tue, 17 Nov
|
||||
2009) | 1 line outboundbroadcast isn't set at this time, since it
|
||||
is set after the message is transmited, so we must use other
|
||||
criteria to determine the need for broadcast on a setup
|
||||
..........
|
||||
|
||||
2009-11-14 00:20 +0000 [r1310-1322] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, q931.c, pri_facility.c, pri_facility.h,
|
||||
libpri.h: Reimplement callback mechanism to handle APDU response
|
||||
messages that we care about. 1) No sent messages will remain in
|
||||
the APDU queue unless they have an active timer to remove them.
|
||||
The dummy call reference call and global call reference call
|
||||
structures will not act like a memory leak to sent messages. 2)
|
||||
The new T-RESPONSE timer will be the generic response guard if
|
||||
the standards do not otherwise specify a timer for a message
|
||||
response. 3) The callback will be called. If it is called because
|
||||
of a response message, then the callback has an opportunity to
|
||||
indicate if more responses are expected.
|
||||
|
||||
* libpri.h: We now have 32 timers. No need to reserve minimum space
|
||||
anymore.
|
||||
|
||||
* pri_internal.h, pri_facility.c: There must be only one source for
|
||||
the invoke id values per D channel group. If there are
|
||||
potentially multiple sources for the invoke id sequence then we
|
||||
could get confused if there are multiple outstanding messages
|
||||
with the same invoke id that get responses.
|
||||
|
||||
2009-11-11 00:22 +0000 [r1291] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* pri_internal.h, q921.c: Make sure we also revive links for PRIs,
|
||||
not just PTMP TE BRIs when we get a disconnect message
|
||||
|
||||
2009-11-10 21:51 +0000 [r1283] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_internal.h, q931.c, pri_facility.c, pri_facility.h: The
|
||||
facility ie queue needs to remove facilities that have been sent.
|
||||
The facility ie queue needs to remove facilities that have been
|
||||
sent. Otherwise, the queue just grows until the call is
|
||||
terminated. AOC messages can clog the queue during a long call
|
||||
and the dummy call reference may never be deleted. Also removed
|
||||
unneeded elements of struct apdu_event. The callback function was
|
||||
not a good idea since many facility messages do not have
|
||||
responses and the callback would prevents removal of events from
|
||||
the list.
|
||||
|
||||
2009-11-10 20:25 +0000 [r1276] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: Re-add back in support for TE initiated layer 2
|
||||
activation
|
||||
|
||||
2009-11-10 19:27 +0000 [r1268-1275] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, q931.c, libpri.h: Add dummy call reference
|
||||
support. Fixes problem where PTMP NT mode responds erroneously to
|
||||
a FACILITY message from a phone on the dummy call reference.
|
||||
LibPRI behaved as if the dummy call reference were an invalid
|
||||
call reference and proceeded to respond on the global call
|
||||
reference.
|
||||
|
||||
* pri_internal.h: Remove unused callingsubaddr[].
|
||||
|
||||
2009-11-03 17:19 +0000 [r1255-1261] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_q931.h, q931.c: Unknown IE 50 (cs5, Unknown Information
|
||||
Element) Add code to recognize the code set 5 ie 50 (calling
|
||||
party category) to suppress the unknown IE message. (closes issue
|
||||
#13828) Reported by: fdecher Patches:
|
||||
libpri_ie50_cs5-trunk.diff3.txt uploaded by alecdavis (license
|
||||
585) Tested by: alecdavis
|
||||
|
||||
* q931.c: NT PTMP did not report busy when calling a busy phone.
|
||||
The caller would not get a busy indication when calling a busy
|
||||
phone. Timer T303 is not supposed to be stopped when
|
||||
RELEASE_COMPLETE received. When T303 expires we will now report
|
||||
the last clearing cause code to the caller if we received one.
|
||||
|
||||
2009-10-23 23:47 +0000 [r1242-1249] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_internal.h, pri_facility.c: Add subaddress handling to
|
||||
existing messages and functions. Connected line updates when
|
||||
transfering calls does not completely support subaddresses yet.
|
||||
|
||||
* pri.c, pri_internal.h, pri_q921.h, pri_q931.h, q921.c, q931.c,
|
||||
pri_facility.c, pri_facility.h, libpri.h: Add BRI PTMP NT mode,
|
||||
HOLD/RETRIEVE, Call rerouting/deflection, and keypad facility
|
||||
support. * Added support for BRI PTMP NT mode. (Overlap dialing
|
||||
NT -> TE not supported.) * Added handling of received
|
||||
HOLD/RETRIEVE messages and the optional ability to transfer a
|
||||
held call on disconnect similar to an analog phone. * Added
|
||||
CallRerouting/CallDeflection support for Q.SIG, ETSI PTP, ETSI
|
||||
PTMP. Will reroute/deflect an outgoing call when receive the
|
||||
message. Can use the DAHDISendCallreroutingFacility to send the
|
||||
message for the supported switches. * Added ability to
|
||||
send/receive keypad digits in the SETUP message. Send keypad
|
||||
digits in SETUP message:
|
||||
Dial(DAHDI/g1[/K<keypad_digits>][/extension]) Access any received
|
||||
keypad digits in SETUP message by: ${CHANNEL(keypad_digits)}
|
||||
(closes issue #15048) Tested by: rmudgett, mattf
|
||||
|
||||
2009-10-22 16:16 +0000 [r1230] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, pri_q931.h, q931.c, libpri.h: Add support
|
||||
for calling and called subaddress. Partial support for COLP
|
||||
subaddress. The Telecom Specs in NZ suggests that SUB ADDRESS is
|
||||
always on, so doing "desk to desk" between offices each with an
|
||||
asterisk box over the ISDN should then be possible, without a
|
||||
whole load of DDI numbers required. (closes issue #15604)
|
||||
Reported by: alecdavis Patches: libpri_subaddr_trunk.diff11.txt
|
||||
uploaded by alecdavis (license 585) Some minor modificatons were
|
||||
made. Tested by: alecdavis, rmudgett Review:
|
||||
https://reviewboard.asterisk.org/r/406/
|
||||
|
||||
2009-10-19 22:49 +0000 [r1219-1220] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Fix call state ie transmission. Sending a STATUS message
|
||||
failed to include the call state ie for some reason. We will now
|
||||
always send a call state ie when a message ie list includes one.
|
||||
|
||||
* q931.c: Fix comparision of invalid party name and number structs
|
||||
in comparison functions.
|
||||
|
||||
2009-10-15 22:34 +0000 [r1212] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_facility.c: Take diverted-to-number from DivLegInfo1 and use
|
||||
it as connected number. If no connected number is signaled in the
|
||||
CONNECT message we will use the last diverted to number. (issue
|
||||
#14292) Reported by: tomaso Patches:
|
||||
divleginfo1_to_connectednum.patch uploaded by tomaso (license
|
||||
564) (Used as a guide since it no longer will apply.) (This patch
|
||||
is unrelated to the issue.)
|
||||
|
||||
2009-10-14 19:03 +0000 [r1191-1205] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: In q931_getcall(): Simplify test and add related switch
|
||||
types.
|
||||
|
||||
* q931.c: Reduce future conflicts when adding ie's to the SETUP
|
||||
message.
|
||||
|
||||
2009-10-12 17:17 +0000 [r1177] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, pri_q931.h, q931.c, pri_facility.c:
|
||||
Miscellaneous changes: * Removed unnecessary
|
||||
Q931_IE_CONNECTED_NUM ie from setup_ack_ies[]. * Added internal
|
||||
state Q931_CALL_STATE_NOT_SET to Q.931 state enum. * Made
|
||||
q931_is_ptmp() take a const pointer. * pri_facility.c: Some
|
||||
preparations for subaddressing. * pri.c: Eliminate use of a magic
|
||||
number.
|
||||
|
||||
2009-10-09 23:20 +0000 [r1169] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Conditional out noisy and redundant ASN.1 parse dump of
|
||||
facility ie contents. 1) Outgoing messages have the facility ie
|
||||
ASN.1 decoded and dumped when the ie is added to the message. The
|
||||
whole message is then dumped. 2) Incoming messages have the
|
||||
facility ie ASN.1 decoded and dumped when the ie is processed.
|
||||
The whole message has already been dumped.
|
||||
|
||||
2009-10-07 18:34 +0000 [r1151-1152] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_facility.c: Sent Q.SIG call rerouting message fixes. a)
|
||||
Account for pSS1InfoElement where the bearer capability for the
|
||||
new rerouted call is described. The call could be a fax or data
|
||||
call, let's use the appropriate signaling to avoid call rejects
|
||||
on the other end. b) Handle calling number appropriately, number
|
||||
can be prohibited or non-existent. c) Add calling name if
|
||||
available. d) Use the diversion counter from DivLegInfo2 (if was
|
||||
present in the incoming Setup) and increment. (issue #14292)
|
||||
Reported by: tomaso Patches:
|
||||
libpri-1.4-2009-01-29-rerouting-0.1.9.patch uploaded by tomaso
|
||||
(license 564) (Used as a guide since it no longer will apply.)
|
||||
(This patch is unrelated to the issue.)
|
||||
|
||||
* pri.c, pri_q921.h, q921.c: Merged revisions 1143, 1144 from
|
||||
https://origsvn.digium.com/svn/libpri/tags/1.4.10.2 ..........
|
||||
r1144 | mattf | 2009-09-29 10:32:23 -0500 (Tue, 29 Sep 2009) | 1
|
||||
line This fix is more like the fix that was used to resolve the
|
||||
issue for the PRI case .......... r1143 | mattf | 2009-09-28
|
||||
14:07:01 -0500 (Mon, 28 Sep 2009) | 1 line Changes for 1.4.10.2
|
||||
..........
|
||||
|
||||
2009-09-22 17:12 +0000 [r1120] Jeff Peeler <jpeeler@digium.com>
|
||||
|
||||
* q931.c: Fix call reference to be associated with the D channel
|
||||
message was received The problem is that once a call reference
|
||||
was associated with a particular D channel, it always was. This
|
||||
created an issue with NFAS when the secondary D channel became
|
||||
active as the messages were still being sent on the non-active D
|
||||
channel. (closes issue #14959) Reported by: remiq Patches:
|
||||
bug14959.patch uploaded by jpeeler (license 325) Tested by: remiq
|
||||
|
||||
2009-09-22 02:23 +0000 [r1107] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c: Update pri_event2str() to current defined events.
|
||||
|
||||
2009-09-18 00:31 +0000 [r1097] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Another place where timeout events with subcmds should
|
||||
clear any old subcmds.
|
||||
|
||||
2009-09-15 22:24 +0000 [r1084] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Timeout events with subcmds should clear any old subcmds.
|
||||
|
||||
2009-09-14 22:32 +0000 [r1077] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* q921.c: Output multiline output with multiple calls to
|
||||
pri_message, so that logs look normal in Asterisk
|
||||
|
||||
2009-09-13 22:54 +0000 [r1072] Dwayne M. Hubbard <dwayne.hubbard@gmail.com>
|
||||
|
||||
* pri_q931.h, q931.c: Add SERVICE message support for the
|
||||
'national' switchtype This set of changes integrates SERVICE
|
||||
message support for the 'national' switchtype. The 'national'
|
||||
switchtype uses the 0x43 protocol discriminator. The 'national'
|
||||
SERVICE/SERVICE ACKNOWLEDGE and AT&T SERVICE/SERVICE ACKNOWLEDGE
|
||||
message values are opposite of each other. This is handled by
|
||||
first determining which protocol discriminator is in use, then
|
||||
responding with the appropriate SERVICE ACKNOWLEDGE value. AT&T
|
||||
SERVICE messages use the 0x3 protocol discriminator. (closes
|
||||
issue #15803) Reported by: dhubbard Review:
|
||||
https://reviewboard.asterisk.org/r/347/
|
||||
|
||||
2009-09-02 20:19 +0000 [r1059-1061] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_internal.h, pri_q931.h, q931.c: Converted Q931_CALL_STATE_xxx
|
||||
defines to an enum.
|
||||
|
||||
* q921.c, q931.c: Optimized calls to pri_schedule_del(). There is
|
||||
no need to test if a scheduled event is running before calling
|
||||
pri_schedule_del().
|
||||
|
||||
* prisched.c: Cleaned up scheduled events handling code. * Fixed
|
||||
pri_schedule_event() to return 0 on error instead of -1. Zero is
|
||||
a safer value to return. Users would not think that a timer was
|
||||
scheduled. * Fixed potential for pri_schedule_del() to write out
|
||||
of bounds of pri_sched[]. The out of bounds access could occur
|
||||
when pri_schedule_event() returned -1. * Made use all pri_sched[]
|
||||
entries. pri_sched[0] was previously unused. * Removed some
|
||||
unneeded code and recursion since scheduling only runs on master
|
||||
D channel structures. * Added doxygen comments. * Renamed struct
|
||||
pri *pri variables to struct pri *ctrl in this file.
|
||||
|
||||
2009-08-31 22:57 +0000 [r1042-1051] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c, libpri.h: Make event channel parameter encoding
|
||||
consistent. Also make sure that service maintenance messages have
|
||||
the channel id parameters reinitialized for each message since
|
||||
they are sent over the global call reference.
|
||||
|
||||
* pri.c, pri_internal.h, q931.c, libpri.h: Split justsignalling
|
||||
into cis_call and cis_auto_disconnect functionality.
|
||||
|
||||
2009-08-26 15:24 +0000 [r1006-1028] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Fix BRI PTP broken by -r790.
|
||||
|
||||
* q931.c: Put connected name in display ie for CONNECT message.
|
||||
|
||||
* q931.c: Fix ie ordering in some ie lists for send_message().
|
||||
|
||||
* q931.c: Make dump_channel_id() handle variable length fields.
|
||||
Also did some other minor miscellaneous changes.
|
||||
|
||||
* q931.c: Make sure reversecharge is initialized.
|
||||
|
||||
2009-08-21 19:51 +0000 [r1000] Jason Parker <jparker@digium.com>
|
||||
|
||||
* Makefile: Add -n to ldconfig on HURD too. (closes issue #15130)
|
||||
Reported by: tzafrir Patches: osarch_hurd.diff uploaded by
|
||||
tzafrir (license 46)
|
||||
|
||||
2009-08-20 15:52 +0000 [r994] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Made the call state to string table use the state
|
||||
defines.
|
||||
|
||||
2009-08-18 23:53 +0000 [r982] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* rose.c, rosetest.c, rose_internal.h, pri.c, pri_internal.h,
|
||||
Makefile, q931.c, rose.h, rose_etsi_diversion.c (added),
|
||||
pri_facility.c, pri_facility.h, libpri.h, rose_etsi_ect.c
|
||||
(added): Add COLP support to libpri for ETSI PTP, ETSI PTMP, and
|
||||
Q.SIG. Add Connected Line Presentation (COLP) support to
|
||||
chan_dahdi/libpri as an addition to issue 8824. This is the
|
||||
libpri portion. COLP support is now available for ETSI PTP, ETSI
|
||||
PTMP, and Q.SIG with this patch. (closes issue #14068) Tested by:
|
||||
rmudgett Review: https://reviewboard.asterisk.org/r/339/
|
||||
|
||||
2009-08-18 20:59 +0000 [r976] Jeff Peeler <jpeeler@digium.com>
|
||||
|
||||
* Makefile: Allow custom CPU optimization flags Added make variable
|
||||
LIBPRI_OPT to set optimization level. By default the optimization
|
||||
level is now set to -O2. (closes issue #12676) Reported by:
|
||||
tzafrir Patches: libpri_opt.diff uploaded by tzafrir (license 46)
|
||||
|
||||
2009-08-07 15:53 +0000 [r968] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* rose_qsig_diversion.c: Corrected standard document reference.
|
||||
|
||||
2009-07-23 20:53 +0000 [r952] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_facility.c: Fixed potential NULL pointer dereference.
|
||||
|
||||
2009-06-26 19:50 +0000 [r914-921] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri.c: Fix potential buffer overflow in pri_dump_info_str(). *
|
||||
Created pri_snprintf() to prevent buffer overflow in
|
||||
pri_dump_info_str(). * Extracted timer name to timer number table
|
||||
from pri_timer2idx() so pri_dump_info_str() can use it.
|
||||
|
||||
* pri_internal.h: Eliminate local version of PRI_MAX_TIMERS.
|
||||
|
||||
* libpri.h: Doxygenify the timer comments.
|
||||
|
||||
* pri_internal.h, q931.c: Added printf format attribute to
|
||||
pri_message() and pri_error() and fixed some detected errors.
|
||||
|
||||
2009-06-25 18:53 +0000 [r907] Sean Bright <sean@malleable.com>
|
||||
|
||||
* pri.c, pri_internal.h, q931.c, libpri.h: Add support for sending
|
||||
Reverse Charging Indication IE on ISDN PRI. Add the ability to
|
||||
transmit a Reverse Charging Indication IE during a SETUP message.
|
||||
In passing, re-work some of the receive logic to be forwards
|
||||
compatible with new RCI values that may be added in the future.
|
||||
Also removed the PRI_REVERSECHARGE_SUPPORT define that I added on
|
||||
the last commit since we can just check for
|
||||
PRI_REVERSECHARGE_NONE or _REQUESTED on the Asterisk side to
|
||||
determine support for this. Special thanks to rmudgett who could
|
||||
have written this in half the time he spent reviewing it, but
|
||||
instead talked me through it. Much appreciated! (issue #13760)
|
||||
Reported by: mrgabu Review:
|
||||
https://reviewboard.asterisk.org/r/292/
|
||||
|
||||
2009-06-25 17:35 +0000 [r894-901] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* libpri.h: Convert PRI_TIMER_xxx to an enum so PRI_MAX_TIMERS can
|
||||
be automatically adjusted.
|
||||
|
||||
* pri.c, pri_timers.h (removed), libpri.h: Make it easier to add
|
||||
more timers/counters and vary the defaults based upon switchtype.
|
||||
|
||||
2009-06-24 18:19 +0000 [r878-885] Sean Bright <sean@malleable.com>
|
||||
|
||||
* pri_internal.h, q931.c, libpri.h: Capture and expose the Reverse
|
||||
Charging Indication IE on ISDN PRI. (issue #13760) Reported by:
|
||||
mrgabu Patches: 20090619_libpri_1.4.patch uploaded by seanbright
|
||||
(license 71) Tested by: seanbright, pruonckk Review:
|
||||
https://reviewboard.asterisk.org/r/291/
|
||||
|
||||
* pri_internal.h, q931.c, libpri.h: Revert unintentional changes
|
||||
|
||||
* pri_internal.h, q931.c, /, libpri.h: Set reviewboard property.
|
||||
|
||||
2009-06-12 14:29 +0000 [r865] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_facility.c: Miscellaneous minor changes.
|
||||
|
||||
2009-06-09 19:47 +0000 [r859] Matthew Fredrickson <creslin@digium.com>
|
||||
|
||||
* 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-06-03 22:51 +0000 [r836-848] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* asn1_primitive.c: Made ASN.1 memory dump also display printable
|
||||
characters.
|
||||
|
||||
* q931.c: Renamed callstate2str() to q931_call_state_str().
|
||||
|
||||
* q931.c: Made transmit_facility() debug message indiate to which
|
||||
message the facility ie is being added.
|
||||
|
||||
2009-05-29 15:39 +0000 [r824] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Renamed local struct pri *pri variables to struct pri
|
||||
*ctrl in q931.c. The context tagging for my editor is much
|
||||
happier now that the struct and the variable do not have the same
|
||||
name. (At least for this file.)
|
||||
|
||||
2009-05-20 15:03 +0000 [r804] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c: Removed usage of FUNC_DUMP(), FUNC_RECV(), and
|
||||
FUNC_SEND() defines. They did not really help and hindered easy
|
||||
lookup of parameter types.
|
||||
|
||||
2009-05-13 15:17 +0000 [r798] Kevin P. Fleming <kpfleming@digium.com>
|
||||
|
||||
* pri.c, pri_q931.h, q931.c, libpri.h: Add 'const' qualifier to
|
||||
character string argument to keypad facility API calls These API
|
||||
calls do not modify the string supplied, and should not be
|
||||
allowed to modify it, so this patch adds a 'const' qualifier to
|
||||
that argument to allow the compiler to enforce this restriction
|
||||
(and allow callers of the API that already have a 'const' pointer
|
||||
to be able to pass it to this API).
|
||||
|
||||
2009-05-07 16:21 +0000 [r790-794] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_internal.h, pri_q931.h, q931.c: Minor code clean up.
|
||||
|
||||
* q931.c: Avoid a stale pointer crash if the TE BRI TEI is removed
|
||||
when active calls exist. Made the q931_call record point to the
|
||||
master D channel control structure instead of the BRI TEI
|
||||
subchannel control structure. When a layer 3 message is sent, the
|
||||
current TEI subchannel control structure is used.
|
||||
|
||||
2009-05-05 22:25 +0000 [r786] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_q931.h: Added Q.931 call state description comments.
|
||||
|
||||
2009-05-01 22:47 +0000 [r782] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_q931.h, q921.c: Comment changes.
|
||||
|
||||
2009-04-21 23:32 +0000 [r766-772] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* rose.c, rosetest.c, rose_internal.h, Makefile, rose.h,
|
||||
rose_qsig_aoc.c (added), pri_facility.c: Added Q.SIG
|
||||
Advice-Of-Charge encode/decode routines.
|
||||
|
||||
* asn1_primitive.c (added), pri_internal.h, rose_qsig_name.c
|
||||
(added), Makefile, q931.c, asn1.h (added), rose_qsig_mwi.c
|
||||
(added), rose.c (added), rosetest.c (added), rose_internal.h
|
||||
(added), rose_other.c (added), rose.h (added), rose_address.c
|
||||
(added), rose_qsig_diversion.c (added), rose_etsi_aoc.c (added),
|
||||
pri_facility.c, rose_qsig_ct.c (added), pri_facility.h,
|
||||
rose_q931.c (added), libpri.h: ROSE ASN.1 facility encode and
|
||||
decode rewrite of existing messages. Several components are now
|
||||
parsed correctly. Most notably: PartyNumber and Q.SIG Name.
|
||||
|
||||
2009-04-14 15:05 +0000 [r732] Jeff Peeler <jpeeler@digium.com>
|
||||
|
||||
* pri.c, pri_internal.h, pri_q921.h, pri_q931.h, q921.c, q931.c,
|
||||
libpri.h: Add service maintenance message support This adds
|
||||
support for two new message types: Service and Service
|
||||
Acknowledge. When a channel receives a service message it will
|
||||
either take the channel in or out of service and then send a
|
||||
service acknowledgment. Although not enforced here (enforced in
|
||||
chan_dahdi), the service messages are only supported with switch
|
||||
types 4ess/5ess. The required Asterisk changes will be coming
|
||||
next. (issue #3450) Reported by: cmaj
|
||||
|
||||
2009-04-02 19:33 +0000 [r726] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* pri_facility.c: Comment changes and some string content
|
||||
corrections.
|
||||
|
||||
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.
|
||||
|
||||
62
Makefile
62
Makefile
@@ -41,15 +41,55 @@ SONAME:=1.4
|
||||
|
||||
STATIC_LIBRARY=libpri.a
|
||||
DYNAMIC_LIBRARY:=libpri.so.$(SONAME)
|
||||
STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o version.o
|
||||
DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo version.lo
|
||||
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS)
|
||||
STATIC_OBJS= \
|
||||
copy_string.o \
|
||||
pri.o \
|
||||
q921.o \
|
||||
prisched.o \
|
||||
q931.o \
|
||||
pri_facility.o \
|
||||
asn1_primitive.o \
|
||||
rose.o \
|
||||
rose_address.o \
|
||||
rose_etsi_aoc.o \
|
||||
rose_etsi_diversion.o \
|
||||
rose_etsi_ect.o \
|
||||
rose_other.o \
|
||||
rose_q931.o \
|
||||
rose_qsig_aoc.o \
|
||||
rose_qsig_ct.o \
|
||||
rose_qsig_diversion.o \
|
||||
rose_qsig_mwi.o \
|
||||
rose_qsig_name.o \
|
||||
version.o
|
||||
DYNAMIC_OBJS= \
|
||||
copy_string.lo \
|
||||
pri.lo \
|
||||
q921.lo \
|
||||
prisched.lo \
|
||||
q931.lo \
|
||||
pri_facility.lo \
|
||||
asn1_primitive.lo \
|
||||
rose.lo \
|
||||
rose_address.lo \
|
||||
rose_etsi_aoc.lo \
|
||||
rose_etsi_diversion.lo \
|
||||
rose_etsi_ect.lo \
|
||||
rose_other.lo \
|
||||
rose_q931.lo \
|
||||
rose_qsig_aoc.lo \
|
||||
rose_qsig_ct.lo \
|
||||
rose_qsig_diversion.lo \
|
||||
rose_qsig_mwi.lo \
|
||||
rose_qsig_name.lo \
|
||||
version.lo
|
||||
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS) $(LIBPRI_OPT)
|
||||
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))
|
||||
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX XGNUX))
|
||||
LDCONFIG_FLAGS=-n
|
||||
else
|
||||
ifeq (${OSARCH},FreeBSD)
|
||||
@@ -74,7 +114,14 @@ PRIVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) build_tools/make_version .)
|
||||
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesnt support it.
|
||||
ifeq ($(PROC),sparc64)
|
||||
PROC=ultrasparc
|
||||
CFLAGS += -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
|
||||
LIBPRI_OPT = -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
|
||||
else
|
||||
LIBPRI_OPT = -O2
|
||||
endif
|
||||
|
||||
ifeq ($(CPUARCH),i686)
|
||||
CFLAGS += -m32
|
||||
SOFLAGS += -m32
|
||||
endif
|
||||
|
||||
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
@@ -102,7 +149,7 @@ install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
ifneq (${OSARCH},SunOS)
|
||||
install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
|
||||
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
|
||||
#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
|
||||
@@ -132,6 +179,9 @@ testprilib: testprilib.o
|
||||
pridump: pridump.o
|
||||
$(CC) -o pridump pridump.o -L. -lpri $(CFLAGS)
|
||||
|
||||
rosetest: rosetest.o
|
||||
$(CC) -o rosetest rosetest.o -L. -lpri $(CFLAGS)
|
||||
|
||||
MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
|
||||
|
||||
%.o: %.c
|
||||
|
||||
257
asn1.h
Normal file
257
asn1.h
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief ASN.1 definitions and prototypes
|
||||
*
|
||||
* \details
|
||||
* This file contains all ASN.1 primitive data structures and
|
||||
* definitions needed for ROSE component encoding and decoding.
|
||||
*
|
||||
* ROSE - Remote Operations Service Element
|
||||
* ASN.1 - Abstract Syntax Notation 1
|
||||
* APDU - Application Protocol Data Unit
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
#ifndef _LIBPRI_ASN1_H
|
||||
#define _LIBPRI_ASN1_H
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*! ASN.1 Identifier Octet - Tag class bits */
|
||||
#define ASN1_CLASS_MASK 0xc0
|
||||
#define ASN1_CLASS_UNIVERSAL 0x00 /*!< Universal primitive data types */
|
||||
#define ASN1_CLASS_APPLICATION 0x40 /*!< Application wide data tag */
|
||||
#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /*!< Context specifc data tag */
|
||||
#define ASN1_CLASS_PRIVATE 0xc0 /*!< Private organization data tag */
|
||||
|
||||
/*! ASN.1 Identifier Octet - Primitive/Constructor bit */
|
||||
#define ASN1_PC_MASK 0x20
|
||||
#define ASN1_PC_PRIMITIVE 0x00
|
||||
#define ASN1_PC_CONSTRUCTED 0x20
|
||||
|
||||
/*! ASN.1 Identifier Octet - Universal data types */
|
||||
#define ASN1_TYPE_MASK 0x1f
|
||||
#define ASN1_TYPE_INDEF_TERM 0x00 /* 0 */
|
||||
#define ASN1_TYPE_BOOLEAN 0x01 /* 1 */
|
||||
#define ASN1_TYPE_INTEGER 0x02 /* 2 */
|
||||
#define ASN1_TYPE_BIT_STRING 0x03 /* 3 */
|
||||
#define ASN1_TYPE_OCTET_STRING 0x04 /* 4 */
|
||||
#define ASN1_TYPE_NULL 0x05 /* 5 */
|
||||
#define ASN1_TYPE_OBJECT_IDENTIFIER 0x06 /* 6 */
|
||||
#define ASN1_TYPE_OBJECT_DESCRIPTOR 0x07 /* 7 */
|
||||
#define ASN1_TYPE_EXTERN 0x08 /* 8 */
|
||||
#define ASN1_TYPE_REAL 0x09 /* 9 */
|
||||
#define ASN1_TYPE_ENUMERATED 0x0a /* 10 */
|
||||
#define ASN1_TYPE_EMBEDDED_PDV 0x0b /* 11 */
|
||||
#define ASN1_TYPE_UTF8_STRING 0x0c /* 12 */
|
||||
#define ASN1_TYPE_RELATIVE_OID 0x0d /* 13 */
|
||||
/* 0x0e & 0x0f are reserved for future ASN.1 editions */
|
||||
#define ASN1_TYPE_SEQUENCE 0x10 /* 16 */
|
||||
#define ASN1_TYPE_SET 0x11 /* 17 */
|
||||
#define ASN1_TYPE_NUMERIC_STRING 0x12 /* 18 */
|
||||
#define ASN1_TYPE_PRINTABLE_STRING 0x13 /* 19 */
|
||||
#define ASN1_TYPE_TELETEX_STRING 0x14 /* 20 */
|
||||
#define ASN1_TYPE_VIDEOTEX_STRING 0x15 /* 21 */
|
||||
#define ASN1_TYPE_IA5_STRING 0x16 /* 22 */
|
||||
#define ASN1_TYPE_UTC_TIME 0x17 /* 23 */
|
||||
#define ASN1_TYPE_GENERALIZED_TIME 0x18 /* 24 */
|
||||
#define ASN1_TYPE_GRAPHIC_STRING 0x19 /* 25 */
|
||||
#define ASN1_TYPE_VISIBLE_STRING 0x1a /* 26 */
|
||||
#define ASN1_TYPE_ISO646_STRING 0x1a /* 26 */
|
||||
#define ASN1_TYPE_GENERAL_STRING 0x1b /* 27 */
|
||||
#define ASN1_TYPE_UNIVERSAL_STRING 0x1c /* 28 */
|
||||
#define ASN1_TYPE_CHAR_STRING 0x1d /* 29 */
|
||||
#define ASN1_TYPE_BMP_STRING 0x1e /* 30 */
|
||||
#define ASN1_TYPE_EXTENSION 0x1f /* 31 */
|
||||
|
||||
#define ASN1_TAG_SEQUENCE (ASN1_CLASS_UNIVERSAL | ASN1_PC_CONSTRUCTED | ASN1_TYPE_SEQUENCE)
|
||||
#define ASN1_TAG_SET (ASN1_CLASS_UNIVERSAL | ASN1_PC_CONSTRUCTED | ASN1_TYPE_SET)
|
||||
|
||||
#define ASN1_INDEF_TERM (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_INDEF_TERM)
|
||||
#define ASN1_INDEF_TERM_LEN 2
|
||||
|
||||
struct asn1_oid {
|
||||
/*! \brief Number of subidentifier values in OID list */
|
||||
u_int16_t num_values;
|
||||
|
||||
/*!
|
||||
* \brief OID subidentifier value list
|
||||
* \note The first value is really the first two OID subidentifiers.
|
||||
* They are compressed using this formula:
|
||||
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
|
||||
*/
|
||||
u_int16_t value[10];
|
||||
};
|
||||
|
||||
#define ASN1_CALL(new_pos, do_it) \
|
||||
do \
|
||||
{ \
|
||||
(new_pos) = (do_it); \
|
||||
if (!(new_pos)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*! \brief Determine the ending position of the set or sequence to verify the length. */
|
||||
#define ASN1_END_SETUP(component_end, offset, length, pos, end) \
|
||||
do { \
|
||||
if ((length) < 0) { \
|
||||
(offset) = ASN1_INDEF_TERM_LEN; \
|
||||
(component_end) = (end); \
|
||||
} else { \
|
||||
(offset) = 0; \
|
||||
(component_end) = (pos) + (length); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*! \brief Account for the indefinite length terminator of the set or sequence. */
|
||||
#define ASN1_END_FIXUP(ctrl, pos, offset, component_end, end) \
|
||||
do { \
|
||||
if (offset) { \
|
||||
ASN1_CALL((pos), asn1_dec_indef_end_fixup((ctrl), (pos), (end))); \
|
||||
} else if ((pos) != (component_end)) { \
|
||||
if ((ctrl)->debug & PRI_DEBUG_APDU) { \
|
||||
pri_message((ctrl), \
|
||||
" Skipping unused constructed component octets!\n"); \
|
||||
} \
|
||||
(pos) = (component_end); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASN1_DID_NOT_EXPECT_TAG(ctrl, tag) \
|
||||
do { \
|
||||
if ((ctrl)->debug & PRI_DEBUG_APDU) { \
|
||||
pri_message((ctrl), " Did not expect: %s\n", asn1_tag2str(tag)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASN1_CHECK_TAG(ctrl, actual_tag, match_tag, expected_tag) \
|
||||
do { \
|
||||
if ((match_tag) != (expected_tag)) { \
|
||||
ASN1_DID_NOT_EXPECT_TAG((ctrl), (actual_tag)); \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
const unsigned char *asn1_dec_tag(const unsigned char *tag_pos, const unsigned char *end,
|
||||
unsigned *tag);
|
||||
const unsigned char *asn1_dec_length(const unsigned char *len_pos,
|
||||
const unsigned char *end, int *length);
|
||||
const unsigned char *asn1_dec_indef_end_fixup(struct pri *ctrl, const unsigned char *pos,
|
||||
const unsigned char *end);
|
||||
|
||||
const unsigned char *asn1_dec_boolean(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, int32_t *value);
|
||||
const unsigned char *asn1_dec_int(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, int32_t *value);
|
||||
const unsigned char *asn1_dec_null(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end);
|
||||
const unsigned char *asn1_dec_oid(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, struct asn1_oid *oid);
|
||||
const unsigned char *asn1_dec_string_bin(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end, size_t buf_size,
|
||||
unsigned char *str, size_t *str_len);
|
||||
const unsigned char *asn1_dec_string_max(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end, size_t buf_size,
|
||||
unsigned char *str, size_t *str_len);
|
||||
|
||||
const char *asn1_tag2str(unsigned tag);
|
||||
void asn1_dump(struct pri *ctrl, const unsigned char *start_asn1,
|
||||
const unsigned char *end);
|
||||
|
||||
|
||||
#define ASN1_LEN_FORM_SHORT 1 /*!< Hint that the final length will be less than 128 octets */
|
||||
#define ASN1_LEN_FORM_LONG_U8 2 /*!< Hint that the final length will be less than 256 octets */
|
||||
#define ASN1_LEN_FORM_LONG_U16 3 /*!< Hint that the final length will be less than 65536 octets */
|
||||
#define ASN1_LEN_INIT(len_pos, end, form_hint) \
|
||||
do { \
|
||||
if ((end) < (len_pos) + (form_hint)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
*(len_pos) = (form_hint); \
|
||||
(len_pos) += (form_hint); \
|
||||
} while (0)
|
||||
|
||||
#define ASN1_LEN_FIXUP(len_pos, component_end, end) \
|
||||
ASN1_CALL((component_end), asn1_enc_length_fixup((len_pos), (component_end), (end)))
|
||||
|
||||
/*! \brief Use to begin encoding explicit tags, SET, and SEQUENCE constructed groupings. */
|
||||
#define ASN1_CONSTRUCTED_BEGIN(len_pos_save, pos, end, tag) \
|
||||
do { \
|
||||
if ((end) < (pos) + (1 + ASN1_LEN_FORM_SHORT)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
*(pos)++ = (tag) | ASN1_PC_CONSTRUCTED; \
|
||||
(len_pos_save) = (pos); \
|
||||
*(pos) = ASN1_LEN_FORM_SHORT; \
|
||||
(pos) += ASN1_LEN_FORM_SHORT; \
|
||||
} while (0)
|
||||
|
||||
/*! \brief Use to end encoding explicit tags, SET, and SEQUENCE constructed groupings. */
|
||||
#define ASN1_CONSTRUCTED_END(len_pos, component_end, end) \
|
||||
ASN1_CALL((component_end), asn1_enc_length_fixup((len_pos), (component_end), (end)))
|
||||
|
||||
#define ASN1_ENC_ERROR(ctrl, msg) \
|
||||
pri_error((ctrl), "%s error: %s\n", __FUNCTION__, (msg))
|
||||
|
||||
unsigned char *asn1_enc_length(unsigned char *len_pos, unsigned char *end,
|
||||
size_t str_len);
|
||||
unsigned char *asn1_enc_length_fixup(unsigned char *len_pos,
|
||||
unsigned char *component_end, unsigned char *end);
|
||||
|
||||
unsigned char *asn1_enc_boolean(unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
int32_t value);
|
||||
unsigned char *asn1_enc_int(unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
int32_t value);
|
||||
unsigned char *asn1_enc_null(unsigned char *pos, unsigned char *end, unsigned tag);
|
||||
unsigned char *asn1_enc_oid(unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
const struct asn1_oid *oid);
|
||||
unsigned char *asn1_enc_string_bin(unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
const unsigned char *str, size_t str_len);
|
||||
unsigned char *asn1_enc_string_max(unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
const unsigned char *str, size_t max_len);
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBPRI_ASN1_H */
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end asn1.h */
|
||||
1306
asn1_primitive.c
Normal file
1306
asn1_primitive.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
777
libpri.h
777
libpri.h
@@ -26,7 +26,14 @@
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* All new global identifiers that are added to this file MUST be
|
||||
* prefixed with PRI_ or pri_ to indicate that they are part of this
|
||||
* library and to reduce potential naming conflicts.
|
||||
*/
|
||||
|
||||
#ifndef _LIBPRI_H
|
||||
#define _LIBPRI_H
|
||||
|
||||
@@ -64,23 +71,32 @@
|
||||
|
||||
/* 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_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_RESTART_ACK 10 /* Restart complete on a given channel (RESTART_ACKNOWLEDGE) */
|
||||
#define PRI_EVENT_FACNAME 11 /* Caller*ID Name received on Facility (DEPRECATED) */
|
||||
#define PRI_EVENT_FACILITY 11 /* Facility received (FACILITY) */
|
||||
#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) */
|
||||
#define PRI_EVENT_SERVICE 19 /* SERVICE maintenance message */
|
||||
#define PRI_EVENT_SERVICE_ACK 20 /* SERVICE maintenance acknowledgement message */
|
||||
#define PRI_EVENT_HOLD 21 /* HOLD request received */
|
||||
#define PRI_EVENT_HOLD_ACK 22 /* HOLD_ACKNOWLEDGE received */
|
||||
#define PRI_EVENT_HOLD_REJ 23 /* HOLD_REJECT received */
|
||||
#define PRI_EVENT_RETRIEVE 24 /* RETRIEVE request received */
|
||||
#define PRI_EVENT_RETRIEVE_ACK 25 /* RETRIEVE_ACKNOWLEDGE received */
|
||||
#define PRI_EVENT_RETRIEVE_REJ 26 /* RETRIEVE_REJECT received */
|
||||
|
||||
/* Simple states */
|
||||
#define PRI_STATE_DOWN 0
|
||||
@@ -101,13 +117,13 @@
|
||||
#define PRI_PROG_CALLER_RETURNED_TO_ISDN (1 << 9)
|
||||
|
||||
/* Numbering plan identifier */
|
||||
#define PRI_NPI_UNKNOWN 0x0
|
||||
#define PRI_NPI_E163_E164 0x1
|
||||
#define PRI_NPI_X121 0x3
|
||||
#define PRI_NPI_F69 0x4
|
||||
#define PRI_NPI_NATIONAL 0x8
|
||||
#define PRI_NPI_PRIVATE 0x9
|
||||
#define PRI_NPI_RESERVED 0xF
|
||||
#define PRI_NPI_UNKNOWN 0x0 /*!< Unknown numbering plan */
|
||||
#define PRI_NPI_E163_E164 0x1 /*!< ISDN/telephony numbering plan (public) */
|
||||
#define PRI_NPI_X121 0x3 /*!< Data numbering plan */
|
||||
#define PRI_NPI_F69 0x4 /*!< Telex numbering plan */
|
||||
#define PRI_NPI_NATIONAL 0x8 /*!< National standard numbering plan */
|
||||
#define PRI_NPI_PRIVATE 0x9 /*!< Private numbering plan */
|
||||
#define PRI_NPI_RESERVED 0xF /*!< Reserved for extension */
|
||||
|
||||
/* Type of number */
|
||||
#define PRI_TON_UNKNOWN 0x0
|
||||
@@ -135,18 +151,51 @@
|
||||
#define PRI_UNKNOWN 0x0
|
||||
|
||||
/* Presentation */
|
||||
#define PRES_ALLOWED_USER_NUMBER_NOT_SCREENED 0x00
|
||||
#define PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN 0x01
|
||||
#define PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN 0x02
|
||||
#define PRES_ALLOWED_NETWORK_NUMBER 0x03
|
||||
#define PRES_PROHIB_USER_NUMBER_NOT_SCREENED 0x20
|
||||
#define PRES_PROHIB_USER_NUMBER_PASSED_SCREEN 0x21
|
||||
#define PRES_PROHIB_USER_NUMBER_FAILED_SCREEN 0x22
|
||||
#define PRES_PROHIB_NETWORK_NUMBER 0x23
|
||||
#define PRES_NUMBER_NOT_AVAILABLE 0x43
|
||||
#define PRI_PRES_NUMBER_TYPE 0x03
|
||||
#define PRI_PRES_USER_NUMBER_UNSCREENED 0x00
|
||||
#define PRI_PRES_USER_NUMBER_PASSED_SCREEN 0x01
|
||||
#define PRI_PRES_USER_NUMBER_FAILED_SCREEN 0x02
|
||||
#define PRI_PRES_NETWORK_NUMBER 0x03
|
||||
|
||||
/* Causes for disconnection */
|
||||
#define PRI_CAUSE_UNALLOCATED 1
|
||||
#define PRI_PRES_RESTRICTION 0x60
|
||||
#define PRI_PRES_ALLOWED 0x00
|
||||
#define PRI_PRES_RESTRICTED 0x20
|
||||
#define PRI_PRES_UNAVAILABLE 0x40
|
||||
#define PRI_PRES_RESERVED 0x60
|
||||
|
||||
#define PRES_ALLOWED_USER_NUMBER_NOT_SCREENED \
|
||||
(PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED)
|
||||
|
||||
#define PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN \
|
||||
(PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN)
|
||||
|
||||
#define PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN \
|
||||
(PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN)
|
||||
|
||||
#define PRES_ALLOWED_NETWORK_NUMBER \
|
||||
(PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER)
|
||||
|
||||
#define PRES_PROHIB_USER_NUMBER_NOT_SCREENED \
|
||||
(PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED)
|
||||
|
||||
#define PRES_PROHIB_USER_NUMBER_PASSED_SCREEN \
|
||||
(PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN)
|
||||
|
||||
#define PRES_PROHIB_USER_NUMBER_FAILED_SCREEN \
|
||||
(PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN)
|
||||
|
||||
#define PRES_PROHIB_NETWORK_NUMBER \
|
||||
(PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER)
|
||||
|
||||
#define PRES_NUMBER_NOT_AVAILABLE \
|
||||
(PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER)
|
||||
|
||||
/* Reverse Charging Indication */
|
||||
#define PRI_REVERSECHARGE_NONE -1
|
||||
#define PRI_REVERSECHARGE_REQUESTED 1
|
||||
|
||||
/* Causes for disconnection (See Q.850) */
|
||||
#define PRI_CAUSE_UNALLOCATED 1 /*!< Called number unassigned. */
|
||||
#define PRI_CAUSE_NO_ROUTE_TRANSIT_NET 2 /* !Q.SIG */
|
||||
#define PRI_CAUSE_NO_ROUTE_DESTINATION 3
|
||||
#define PRI_CAUSE_CHANNEL_UNACCEPTABLE 6
|
||||
@@ -157,6 +206,7 @@
|
||||
#define PRI_CAUSE_NO_ANSWER 19
|
||||
#define PRI_CAUSE_CALL_REJECTED 21
|
||||
#define PRI_CAUSE_NUMBER_CHANGED 22
|
||||
#define PRI_CAUSE_NONSELECTED_USER_CLEARING 26
|
||||
#define PRI_CAUSE_DESTINATION_OUT_OF_ORDER 27
|
||||
#define PRI_CAUSE_INVALID_NUMBER_FORMAT 28
|
||||
#define PRI_CAUSE_FACILITY_REJECTED 29 /* !Q.SIG */
|
||||
@@ -169,6 +219,7 @@
|
||||
#define PRI_CAUSE_ACCESS_INFO_DISCARDED 43 /* !Q.SIG */
|
||||
#define PRI_CAUSE_REQUESTED_CHAN_UNAVAIL 44
|
||||
#define PRI_CAUSE_PRE_EMPTED 45 /* !Q.SIG */
|
||||
#define PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED 47
|
||||
#define PRI_CAUSE_FACILITY_NOT_SUBSCRIBED 50 /* !Q.SIG */
|
||||
#define PRI_CAUSE_OUTGOING_CALL_BARRED 52 /* !Q.SIG */
|
||||
#define PRI_CAUSE_INCOMING_CALL_BARRED 54 /* !Q.SIG */
|
||||
@@ -259,8 +310,8 @@
|
||||
#define PRI_RATE_ADAPT_ASYNC 0x40
|
||||
|
||||
/* Notifications */
|
||||
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
|
||||
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
|
||||
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended (Q.931) (Call is placed on hold) */
|
||||
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed (Q.931) (Call is taken off hold) */
|
||||
#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */
|
||||
#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */
|
||||
#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */
|
||||
@@ -275,12 +326,12 @@
|
||||
#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */
|
||||
#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */
|
||||
#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */
|
||||
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */
|
||||
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */
|
||||
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */
|
||||
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) (cfu, cfb, cfnr) (EN 300 207-1 Section 7.2.1) */
|
||||
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting (EN 300 369-1 Section 7.2) */
|
||||
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active(answered) (EN 300 369-1 Section 7.2) */
|
||||
#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */
|
||||
#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */
|
||||
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */
|
||||
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting (EN 300 207-1 Section 7.2.1) */
|
||||
|
||||
#define PRI_COPY_DIGITS_CALLED_NUMBER
|
||||
|
||||
@@ -305,6 +356,200 @@
|
||||
|
||||
typedef struct q931_call q931_call;
|
||||
|
||||
/* Name character set enumeration values */
|
||||
#define PRI_CHAR_SET_UNKNOWN 0
|
||||
#define PRI_CHAR_SET_ISO8859_1 1
|
||||
#define PRI_CHAR_SET_WITHDRAWN 2
|
||||
#define PRI_CHAR_SET_ISO8859_2 3
|
||||
#define PRI_CHAR_SET_ISO8859_3 4
|
||||
#define PRI_CHAR_SET_ISO8859_4 5
|
||||
#define PRI_CHAR_SET_ISO8859_5 6
|
||||
#define PRI_CHAR_SET_ISO8859_7 7
|
||||
#define PRI_CHAR_SET_ISO10646_BMPSTRING 8
|
||||
#define PRI_CHAR_SET_ISO10646_UTF_8STRING 9
|
||||
|
||||
/*! \brief Q.SIG name information. */
|
||||
struct pri_party_name {
|
||||
/*! \brief TRUE if the name information is valid/present */
|
||||
int valid;
|
||||
/*!
|
||||
* \brief Q.931 presentation-indicator encoded field
|
||||
* \note Must tollerate the Q.931 screening-indicator field values being present.
|
||||
*/
|
||||
int presentation;
|
||||
/*!
|
||||
* \brief Character set the name is using.
|
||||
* \details
|
||||
* unknown(0),
|
||||
* iso8859-1(1),
|
||||
* enum-value-withdrawn-by-ITU-T(2)
|
||||
* iso8859-2(3),
|
||||
* iso8859-3(4),
|
||||
* iso8859-4(5),
|
||||
* iso8859-5(6),
|
||||
* iso8859-7(7),
|
||||
* iso10646-BmpString(8),
|
||||
* iso10646-utf-8String(9)
|
||||
* \details
|
||||
* Set to iso8859-1(1) if unsure what to use.
|
||||
*/
|
||||
int char_set;
|
||||
/*! \brief Name data with null terminator. */
|
||||
char str[64];
|
||||
};
|
||||
|
||||
struct pri_party_number {
|
||||
/*! \brief TRUE if the number information is valid/present */
|
||||
int valid;
|
||||
/*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
|
||||
int presentation;
|
||||
/*! \brief Q.931 Type-Of-Number and numbering-plan encoded fields */
|
||||
int plan;
|
||||
/*! \brief Number data with null terminator. */
|
||||
char str[64];
|
||||
};
|
||||
|
||||
/*!
|
||||
* \note This structure is a place holder for possible future subaddress support
|
||||
* to maintain ABI compatibility.
|
||||
*/
|
||||
struct pri_party_subaddress {
|
||||
/*! \brief TRUE if the subaddress information is valid/present */
|
||||
int valid;
|
||||
/*!
|
||||
* \brief Subaddress type.
|
||||
* \details
|
||||
* nsap(0),
|
||||
* user_specified(2)
|
||||
*/
|
||||
int type;
|
||||
/*!
|
||||
* \brief TRUE if odd number of address signals
|
||||
* \note The odd/even indicator is used when the type of subaddress is
|
||||
* user_specified and the coding is BCD.
|
||||
*/
|
||||
int odd_even_indicator;
|
||||
/*! \brief Length of the subaddress data */
|
||||
int length;
|
||||
/*!
|
||||
* \brief Subaddress data with null terminator.
|
||||
* \note The null terminator is a convenience only since the data could be
|
||||
* BCD/binary and thus have a null byte as part of the contents.
|
||||
*/
|
||||
unsigned char data[32];
|
||||
};
|
||||
|
||||
/*! \brief Information needed to identify an endpoint in a call. */
|
||||
struct pri_party_id {
|
||||
/*! \brief Subscriber name */
|
||||
struct pri_party_name name;
|
||||
/*! \brief Subscriber phone number */
|
||||
struct pri_party_number number;
|
||||
/*! \brief Subscriber subaddress */
|
||||
struct pri_party_subaddress subaddress;
|
||||
};
|
||||
|
||||
/*! \brief Connected Line/Party information */
|
||||
struct pri_party_connected_line {
|
||||
/*! Connected party ID */
|
||||
struct pri_party_id id;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Redirecting Line information.
|
||||
* \details
|
||||
* RDNIS (Redirecting Directory Number Information Service)
|
||||
* Where a call diversion or transfer was invoked.
|
||||
*/
|
||||
struct pri_party_redirecting {
|
||||
/*! Who is redirecting the call (Sent to the party the call is redirected toward) */
|
||||
struct pri_party_id from;
|
||||
/*! Call is redirecting to a new party (Sent to the caller) */
|
||||
struct pri_party_id to;
|
||||
/*! Originally called party (in cases of multiple redirects) */
|
||||
struct pri_party_id orig_called;
|
||||
/*! Number of times the call was redirected */
|
||||
int count;
|
||||
/*! Original reason for redirect (in cases of multiple redirects) */
|
||||
int orig_reason;
|
||||
/*! Redirection reason */
|
||||
int reason;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Information for rerouting/deflecting the call.
|
||||
*/
|
||||
struct pri_rerouting_data {
|
||||
/*!
|
||||
* \brief Updated caller-id information.
|
||||
* \note The information may have been altered by procedure in the private network.
|
||||
*/
|
||||
struct pri_party_id caller;
|
||||
/*!
|
||||
* \note
|
||||
* deflection.to is the new called number and must always be present.
|
||||
*/
|
||||
struct pri_party_redirecting deflection;
|
||||
/*!
|
||||
* \brief Diverting user subscription option to specify if caller is notified.
|
||||
* \details
|
||||
* noNotification(0),
|
||||
* notificationWithoutDivertedToNr(1),
|
||||
* notificationWithDivertedToNr(2),
|
||||
* notApplicable(3) (Status only.)
|
||||
*/
|
||||
int subscription_option;
|
||||
/*! Invocation ID to use when sending a reply to the call rerouting/deflection request. */
|
||||
int invoke_id;
|
||||
};
|
||||
|
||||
/* Subcommands derived from supplementary services. */
|
||||
#define PRI_SUBCMD_REDIRECTING 1
|
||||
#define PRI_SUBCMD_CONNECTED_LINE 2
|
||||
#define PRI_SUBCMD_REROUTING 3
|
||||
|
||||
|
||||
struct pri_subcommand {
|
||||
/*! PRI_SUBCMD_xxx defined values */
|
||||
int cmd;
|
||||
union {
|
||||
/*! Reserve room for possible expansion to maintain ABI compatibility. */
|
||||
char reserve_space[512];
|
||||
struct pri_party_connected_line connected_line;
|
||||
struct pri_party_redirecting redirecting;
|
||||
struct pri_rerouting_data rerouting;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* Max number of subcommands per event message */
|
||||
#define PRI_MAX_SUBCOMMANDS 8
|
||||
|
||||
struct pri_subcommands {
|
||||
int counter_subcmd;
|
||||
struct pri_subcommand subcmd[PRI_MAX_SUBCOMMANDS];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Event channel parameter encoding:
|
||||
* 3322 2222 2222 1111 1111 1100 0000 0000
|
||||
* 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
* xxxx xxxx xxxx xEDC BBBBBBBBB AAAAAAAAA
|
||||
*
|
||||
* Bit field
|
||||
* A - B channel
|
||||
* B - Span (DS1) (0 - 127)
|
||||
* C - DS1 Explicit bit
|
||||
* D - D channel (cis_call) bit (status only)
|
||||
* E - Call is held bit (status only)
|
||||
*
|
||||
* B channel values:
|
||||
* 0 - No channel (ISDN uses for call waiting feature)
|
||||
* 1-127 - B channel #
|
||||
* 0xFF - Any channel (Also if whole channel value is -1 in event)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct pri_event_generic {
|
||||
/* Events with no additional information fall in this category */
|
||||
int e;
|
||||
@@ -328,6 +573,7 @@ typedef struct pri_event_ringing {
|
||||
int progressmask;
|
||||
q931_call *call;
|
||||
char useruserinfo[260]; /* User->User info */
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_ringing;
|
||||
|
||||
typedef struct pri_event_answer {
|
||||
@@ -338,8 +584,10 @@ typedef struct pri_event_answer {
|
||||
int progressmask;
|
||||
q931_call *call;
|
||||
char useruserinfo[260]; /* User->User info */
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_answer;
|
||||
|
||||
/*! Deprecated replaced by struct pri_event_facility. */
|
||||
typedef struct pri_event_facname {
|
||||
int e;
|
||||
char callingname[256];
|
||||
@@ -351,6 +599,24 @@ typedef struct pri_event_facname {
|
||||
int callingplan; /* Dialing plan of Calling entity */
|
||||
} pri_event_facname;
|
||||
|
||||
struct pri_event_facility {
|
||||
int e;
|
||||
char callingname[256]; /*!< Deprecated, preserved for struct pri_event_facname compatibility */
|
||||
char callingnum[256]; /*!< Deprecated, preserved for struct pri_event_facname compatibility */
|
||||
int channel;
|
||||
int cref;
|
||||
/*!
|
||||
* \brief Master call or normal call.
|
||||
* \note Call pointer known about by upper layer.
|
||||
* \note NULL if dummy call reference.
|
||||
*/
|
||||
q931_call *call;
|
||||
int callingpres; /*!< Presentation of Calling CallerID (Deprecated, preserved for struct pri_event_facname compatibility) */
|
||||
int callingplan; /*!< Dialing plan of Calling entity (Deprecated, preserved for struct pri_event_facname compatibility) */
|
||||
struct pri_subcommands *subcmds;
|
||||
q931_call *subcall; /*!< Subcall to send any reply toward. */
|
||||
};
|
||||
|
||||
#define PRI_CALLINGPLANANI
|
||||
#define PRI_CALLINGPLANRDNIS
|
||||
typedef struct pri_event_ring {
|
||||
@@ -376,13 +642,18 @@ typedef struct pri_event_ring {
|
||||
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, backwards compatibility */
|
||||
int progress;
|
||||
int progressmask;
|
||||
char origcalledname[256];
|
||||
char origcallednum[256];
|
||||
int callingplanorigcalled; /* Dialing plan of Originally Called Number */
|
||||
int origredirectingreason;
|
||||
int reversecharge;
|
||||
struct pri_subcommands *subcmds;
|
||||
struct pri_party_id calling; /* Calling Party's info, initially subaddress' */
|
||||
struct pri_party_subaddress called_subaddress; /* Called party's subaddress */
|
||||
char keypad_digits[64]; /* Keypad digits in the SETUP message. */
|
||||
} pri_event_ring;
|
||||
|
||||
typedef struct pri_event_hangup {
|
||||
@@ -390,10 +661,23 @@ typedef struct pri_event_hangup {
|
||||
int channel; /* Channel requested */
|
||||
int cause;
|
||||
int cref;
|
||||
q931_call *call; /* Opaque call pointer */
|
||||
q931_call *call; /* Opaque call pointer of call hanging up. */
|
||||
long aoc_units; /* Advise of Charge number of charged units */
|
||||
char useruserinfo[260]; /* User->User info */
|
||||
} pri_event_hangup;
|
||||
struct pri_subcommands *subcmds;
|
||||
/*!
|
||||
* \brief Opaque held call pointer for possible transfer to active call.
|
||||
* \note The call_held and call_active pointers must not be NULL if
|
||||
* transfer held call on disconnect is available.
|
||||
*/
|
||||
q931_call *call_held;
|
||||
/*!
|
||||
* \brief Opaque active call pointer for possible transfer with held call.
|
||||
* \note The call_held and call_active pointers must not be NULL if
|
||||
* transfer held call on disconnect is available.
|
||||
*/
|
||||
q931_call *call_active;
|
||||
} pri_event_hangup;
|
||||
|
||||
typedef struct pri_event_restart_ack {
|
||||
int e;
|
||||
@@ -409,18 +693,22 @@ typedef struct pri_event_proceeding {
|
||||
int progressmask;
|
||||
int cause;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_proceeding;
|
||||
|
||||
|
||||
typedef struct pri_event_setup_ack {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_setup_ack;
|
||||
|
||||
typedef struct pri_event_notify {
|
||||
int e;
|
||||
int channel;
|
||||
int info;
|
||||
struct pri_subcommands *subcmds;
|
||||
q931_call *call;
|
||||
} pri_event_notify;
|
||||
|
||||
typedef struct pri_event_keypad_digit {
|
||||
@@ -428,14 +716,72 @@ typedef struct pri_event_keypad_digit {
|
||||
int channel;
|
||||
q931_call *call;
|
||||
char digits[64];
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_keypad_digit;
|
||||
|
||||
typedef struct pri_event_service {
|
||||
int e;
|
||||
int channel;
|
||||
int changestatus;
|
||||
} pri_event_service;
|
||||
|
||||
typedef struct pri_event_service_ack {
|
||||
int e;
|
||||
int channel;
|
||||
int changestatus;
|
||||
} pri_event_service_ack;
|
||||
|
||||
struct pri_event_hold {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
struct pri_event_hold_ack {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
struct pri_event_hold_rej {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
int cause;
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
struct pri_event_retrieve {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
int flexible; /* Are we flexible with our channel selection? */
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
struct pri_event_retrieve_ack {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
struct pri_event_retrieve_rej {
|
||||
int e;
|
||||
int channel;
|
||||
q931_call *call;
|
||||
int cause;
|
||||
struct pri_subcommands *subcmds;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
int e;
|
||||
pri_event_generic gen; /* Generic view */
|
||||
pri_event_restart restart; /* Restart view */
|
||||
pri_event_error err; /* Error view */
|
||||
pri_event_facname facname; /* Caller*ID Name on Facility */
|
||||
pri_event_facname facname; /* Caller*ID Name on Facility (Deprecated, use pri_event.facility) */
|
||||
pri_event_ring ring; /* Ring */
|
||||
pri_event_hangup hangup; /* Hang up */
|
||||
pri_event_ringing ringing; /* Ringing */
|
||||
@@ -445,6 +791,15 @@ typedef union {
|
||||
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_service service; /* service message */
|
||||
pri_event_service_ack service_ack; /* service acknowledgement message */
|
||||
struct pri_event_facility facility;
|
||||
struct pri_event_hold hold;
|
||||
struct pri_event_hold_ack hold_ack;
|
||||
struct pri_event_hold_rej hold_rej;
|
||||
struct pri_event_retrieve retrieve;
|
||||
struct pri_event_retrieve_ack retrieve_ack;
|
||||
struct pri_event_retrieve_rej retrieve_rej;
|
||||
} pri_event;
|
||||
|
||||
struct pri;
|
||||
@@ -456,7 +811,7 @@ 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
|
||||
must be NON-BLOCKING! Frames received on the fd should include FCS. Nodetype
|
||||
must be NON-BLOCKING! Frames received on the fd should include FCS. Nodetype
|
||||
must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */
|
||||
struct pri *pri_new(int fd, int nodetype, int switchtype);
|
||||
struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype);
|
||||
@@ -521,7 +876,7 @@ int pri_information(struct pri *pri, q931_call *call, char digit);
|
||||
|
||||
#define PRI_KEYPAD_FACILITY_TX
|
||||
/* Send a keypad facility string of digits */
|
||||
int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits);
|
||||
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
||||
|
||||
/* Answer the incomplete(call without called number) call on the given channel.
|
||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
||||
@@ -531,6 +886,18 @@ int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisd
|
||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
|
||||
/*!
|
||||
* \brief Give connected line information to a call
|
||||
* \note Could be used instead of pri_sr_set_caller_party() before calling pri_setup().
|
||||
*/
|
||||
int pri_connected_line_update(struct pri *pri, q931_call *call, const struct pri_party_connected_line *connected);
|
||||
|
||||
/*!
|
||||
* \brief Give redirection information to a call
|
||||
* \note Could be used instead of pri_sr_set_redirecting_parties() before calling pri_setup().
|
||||
*/
|
||||
int pri_redirecting_update(struct pri *pri, q931_call *call, const struct pri_party_redirecting *redirecting);
|
||||
|
||||
/* Set CRV reference for GR-303 calls */
|
||||
|
||||
|
||||
@@ -548,6 +915,17 @@ int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
#define PRI_HANGUP
|
||||
int pri_hangup(struct pri *pri, q931_call *call, int cause);
|
||||
|
||||
/*!
|
||||
* \brief Set the call hangup fix enable flag.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param enable TRUE to follow Q.931 Section 5.3.2 call hangup better.
|
||||
* FALSE for legacy behaviour. (Default FALSE if not called.)
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_hangup_fix_enable(struct pri *ctrl, int enable);
|
||||
|
||||
#define PRI_DESTROYCALL
|
||||
void pri_destroycall(struct pri *pri, q931_call *call);
|
||||
|
||||
@@ -556,9 +934,20 @@ int pri_restart(struct pri *pri);
|
||||
|
||||
int pri_reset(struct pri *pri, int channel);
|
||||
|
||||
/* handle b-channel maintenance messages */
|
||||
extern int pri_maintenance_service(struct pri *pri, int span, int channel, int changestatus);
|
||||
|
||||
/* Create a new call */
|
||||
q931_call *pri_new_call(struct pri *pri);
|
||||
|
||||
/*!
|
||||
* \brief Deterimine if the given call control pointer is a dummy call.
|
||||
*
|
||||
* \retval TRUE if given call is a dummy call.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
int pri_is_dummy_call(q931_call *call);
|
||||
|
||||
/* Retrieve CRV reference for GR-303 calls. Returns >0 on success. */
|
||||
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
|
||||
|
||||
@@ -573,8 +962,8 @@ extern pri_event *pri_schedule_run(struct pri *pri);
|
||||
extern pri_event *pri_schedule_run_tv(struct pri *pri, const struct timeval *now);
|
||||
|
||||
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
|
||||
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
|
||||
char *called,int calledplan, int ulayer1);
|
||||
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
|
||||
char *called, int calledplan, int ulayer1);
|
||||
|
||||
struct pri_sr *pri_sr_new(void);
|
||||
void pri_sr_free(struct pri_sr *sr);
|
||||
@@ -582,25 +971,91 @@ void pri_sr_free(struct pri_sr *sr);
|
||||
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
|
||||
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
|
||||
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
|
||||
|
||||
/*!
|
||||
* \brief Set the caller party ID information in the call SETUP record.
|
||||
*
|
||||
* \param sr New call SETUP record.
|
||||
* \param caller Caller party ID information to set.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller);
|
||||
/*! \note Use pri_sr_set_caller_party() instead to pass more precise caller information. */
|
||||
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
|
||||
|
||||
/*!
|
||||
* \brief Set the calling subaddress information in the call SETUP record.
|
||||
*
|
||||
* \param sr New call SETUP record.
|
||||
* \param subaddress information to set.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_sr_set_caller_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
|
||||
|
||||
/*!
|
||||
* \brief Set the called subaddress information in the call SETUP record.
|
||||
*
|
||||
* \param sr New call SETUP record.
|
||||
* \param subaddress information to set.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_sr_set_called_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
|
||||
|
||||
/*!
|
||||
* \brief Set the redirecting information in the call SETUP record.
|
||||
*
|
||||
* \param sr New call SETUP record.
|
||||
* \param caller Redirecting information to set.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_sr_set_redirecting_parties(struct pri_sr *sr, const struct pri_party_redirecting *redirecting);
|
||||
/*! \note Use pri_sr_set_redirecting_parties() instead to pass more precise redirecting information. */
|
||||
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
|
||||
|
||||
/*!
|
||||
* \brief Set the keypad digits in the call SETUP record.
|
||||
*
|
||||
* \param sr New call SETUP record.
|
||||
* \param keypad_digits Keypad digits to send.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_sr_set_keypad_digits(struct pri_sr *sr, const char *keypad_digits);
|
||||
|
||||
#define PRI_USER_USER_TX
|
||||
/* Set the user user field. Warning! don't send binary data accross this field */
|
||||
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);
|
||||
void pri_sr_set_reversecharge(struct pri_sr *sr, int requested);
|
||||
|
||||
void pri_call_set_useruser(q931_call *sr, const char *userchars);
|
||||
|
||||
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) */
|
||||
/*!
|
||||
* \brief Set a call as a call indpendent signalling connection (i.e. no bchan)
|
||||
* \note Call will automaticlly disconnect after signalling sent.
|
||||
*/
|
||||
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 */
|
||||
/*!
|
||||
* \brief Set a call as a call indpendent signalling connection (i.e. no bchan)
|
||||
* \note Call will stay connected until explicitly disconnected.
|
||||
*/
|
||||
int pri_sr_set_no_channel_call(struct pri_sr *req);
|
||||
|
||||
/* 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 */
|
||||
int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
|
||||
|
||||
/* Set service message support flag */
|
||||
int pri_set_service_message_support(struct pri *pri, int supportflag);
|
||||
|
||||
#define PRI_2BCT
|
||||
/* Attempt to pass the channels back to the NET side if compatable and
|
||||
* suscribed. Sometimes called 2 bchannel transfer (2BCT) */
|
||||
@@ -656,47 +1111,207 @@ 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);
|
||||
|
||||
/*!
|
||||
* \brief Set the call deflection/rerouting feature enable flag.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param enable TRUE to enable call deflection/rerouting feature.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_reroute_enable(struct pri *ctrl, int enable);
|
||||
|
||||
/*!
|
||||
* \brief Send the CallRerouting/CallDeflection message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param caller Call rerouting/deflecting updated caller data. (NULL if data not updated.)
|
||||
* \param deflection Call rerouting/deflecting redirection data.
|
||||
* \param subscription_option Diverting user subscription option to specify if caller is notified.
|
||||
*
|
||||
* \note
|
||||
* deflection->to is the new called number and must always be present.
|
||||
* \note
|
||||
* subscription option:
|
||||
* noNotification(0),
|
||||
* notificationWithoutDivertedToNr(1),
|
||||
* notificationWithDivertedToNr(2)
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_reroute_call(struct pri *ctrl, q931_call *call, const struct pri_party_id *caller, const struct pri_party_redirecting *deflection, int subscription_option);
|
||||
|
||||
enum PRI_REROUTING_RSP_CODE {
|
||||
/*!
|
||||
* Rerouting invocation accepted and the network provider option
|
||||
* "served user call retention on invocation of diversion"
|
||||
* is "clear call on invocation".
|
||||
*/
|
||||
PRI_REROUTING_RSP_OK_CLEAR,
|
||||
/*!
|
||||
* Rerouting invocation accepted and the network provider option
|
||||
* "served user call retention on invocation of diversion"
|
||||
* is "retain call until alerting begins at the deflected-to user".
|
||||
*/
|
||||
PRI_REROUTING_RSP_OK_RETAIN,
|
||||
PRI_REROUTING_RSP_NOT_SUBSCRIBED,
|
||||
PRI_REROUTING_RSP_NOT_AVAILABLE,
|
||||
/*! Supplementary service interaction not allowed. */
|
||||
PRI_REROUTING_RSP_NOT_ALLOWED,
|
||||
PRI_REROUTING_RSP_INVALID_NUMBER,
|
||||
/*! Deflection to prohibited number (e.g., operator, police, emergency). */
|
||||
PRI_REROUTING_RSP_SPECIAL_SERVICE_NUMBER,
|
||||
/*! Deflection to served user number. */
|
||||
PRI_REROUTING_RSP_DIVERSION_TO_SELF,
|
||||
PRI_REROUTING_RSP_MAX_DIVERSIONS_EXCEEDED,
|
||||
PRI_REROUTING_RSP_RESOURCE_UNAVAILABLE,
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Send the CallRerouteing/CallDeflection response message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param invoke_id Value given by the initiating request.
|
||||
* \param code The result to send.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_rerouting_rsp(struct pri *ctrl, q931_call *call, int invoke_id, enum PRI_REROUTING_RSP_CODE code);
|
||||
|
||||
/*!
|
||||
* \brief Set the call hold feature enable flag.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param enable TRUE to enable call hold feature.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_hold_enable(struct pri *ctrl, int enable);
|
||||
|
||||
/*!
|
||||
* \brief Send the HOLD message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_hold(struct pri *ctrl, q931_call *call);
|
||||
|
||||
/*!
|
||||
* \brief Send the HOLD ACKNOWLEDGE message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_hold_ack(struct pri *ctrl, q931_call *call);
|
||||
|
||||
/*!
|
||||
* \brief Send the HOLD REJECT message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param cause Q.931 cause code for rejecting the hold request.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_hold_rej(struct pri *ctrl, q931_call *call, int cause);
|
||||
|
||||
/*!
|
||||
* \brief Send the RETRIEVE message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param channel Encoded channel id to use. If zero do not send channel id.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_retrieve(struct pri *ctrl, q931_call *call, int channel);
|
||||
|
||||
/*!
|
||||
* \brief Send the RETRIEVE ACKNOWLEDGE message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param channel Encoded channel id to use.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_retrieve_ack(struct pri *ctrl, q931_call *call, int channel);
|
||||
|
||||
/*!
|
||||
* \brief Send the RETRIEVE REJECT message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param cause Q.931 cause code for rejecting the retrieve request.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause);
|
||||
|
||||
/* Get/Set PRI Timers */
|
||||
#define PRI_GETSET_TIMERS
|
||||
int pri_set_timer(struct pri *pri, int timer, int value);
|
||||
int pri_get_timer(struct pri *pri, int timer);
|
||||
int pri_timer2idx(char *timer);
|
||||
int pri_timer2idx(const char *timer_name);
|
||||
|
||||
#define PRI_MAX_TIMERS 32
|
||||
/*! New configurable timers and counters must be added to the end of the list */
|
||||
enum PRI_TIMERS_AND_COUNTERS {
|
||||
PRI_TIMER_N200, /*!< Maximum numer of Q.921 retransmissions */
|
||||
PRI_TIMER_N201, /*!< Maximum numer of octets in an information field */
|
||||
PRI_TIMER_N202, /*!< Maximum numer of transmissions of the TEI identity request message */
|
||||
PRI_TIMER_K, /*!< Maximum number of outstanding I-frames */
|
||||
|
||||
#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 */
|
||||
PRI_TIMER_T200, /*!< Time between SABME's */
|
||||
PRI_TIMER_T201, /*!< Minimum time between retransmissions of the TEI Identity check messages */
|
||||
PRI_TIMER_T202, /*!< Minimum time between transmission of TEI Identity request messages */
|
||||
PRI_TIMER_T203, /*!< Maximum time without exchanging packets */
|
||||
|
||||
#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 */
|
||||
PRI_TIMER_T300,
|
||||
PRI_TIMER_T301, /*!< Maximum time to respond to an ALERT */
|
||||
PRI_TIMER_T302,
|
||||
PRI_TIMER_T303, /*!< Maximum time to wait after sending a SETUP without a response */
|
||||
PRI_TIMER_T304,
|
||||
PRI_TIMER_T305, /*!< Wait for DISCONNECT acknowledge */
|
||||
PRI_TIMER_T306,
|
||||
PRI_TIMER_T307,
|
||||
PRI_TIMER_T308, /*!< Wait for RELEASE acknowledge */
|
||||
PRI_TIMER_T309, /*!< Time active calls can tollerate data link layer being down before clearing. */
|
||||
PRI_TIMER_T310, /*!< Maximum time between receiving a CALL_PROCEEDING and receiving a ALERT/CONNECT/DISCONNECT/PROGRESS */
|
||||
PRI_TIMER_T313, /*!< Wait for CONNECT acknowledge, CPE side only */
|
||||
PRI_TIMER_T314,
|
||||
PRI_TIMER_T316, /*!< Maximum time between transmitting a RESTART and receiving a RESTART ACK */
|
||||
PRI_TIMER_T317,
|
||||
PRI_TIMER_T318,
|
||||
PRI_TIMER_T319,
|
||||
PRI_TIMER_T320,
|
||||
PRI_TIMER_T321,
|
||||
PRI_TIMER_T322,
|
||||
|
||||
#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
|
||||
PRI_TIMER_TM20, /*!< Maximum time awaiting XID response */
|
||||
PRI_TIMER_NM20, /*!< Number of XID retransmits */
|
||||
|
||||
#define PRI_TIMER_TM20 28 /* maximum time avaiting XID response */
|
||||
#define PRI_TIMER_NM20 29 /* number of XID retransmits */
|
||||
PRI_TIMER_T_HOLD, /*!< Maximum time to wait for HOLD request response. */
|
||||
PRI_TIMER_T_RETRIEVE, /*!< Maximum time to wait for RETRIEVE request response. */
|
||||
|
||||
PRI_TIMER_T_RESPONSE, /*!< Maximum time to wait for a typical APDU response. */
|
||||
|
||||
/* Must be last in the enum list */
|
||||
PRI_MAX_TIMERS
|
||||
};
|
||||
|
||||
/* Get PRI version */
|
||||
const char *pri_get_version(void);
|
||||
|
||||
6073
pri_facility.c
6073
pri_facility.c
File diff suppressed because it is too large
Load Diff
366
pri_facility.h
366
pri_facility.h
@@ -31,123 +31,21 @@
|
||||
#define _PRI_FACILITY_H
|
||||
#include "pri_q931.h"
|
||||
|
||||
/* Forward declare some structs */
|
||||
struct fac_extension_header;
|
||||
struct rose_msg_invoke;
|
||||
struct rose_msg_result;
|
||||
struct rose_msg_error;
|
||||
struct rose_msg_reject;
|
||||
|
||||
/* Protocol Profile field */
|
||||
#define Q932_PROTOCOL_MASK 0x1F
|
||||
#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_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
|
||||
#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.7 (ECMA-178) ROSE operations (Transfer) */
|
||||
#define ROSE_CALL_TRANSFER_IDENTIFY 7
|
||||
#define ROSE_CALL_TRANSFER_ABANDON 8
|
||||
#define ROSE_CALL_TRANSFER_INITIATE 9
|
||||
#define ROSE_CALL_TRANSFER_SETUP 10
|
||||
#define ROSE_CALL_TRANSFER_ACTIVE 11
|
||||
#define ROSE_CALL_TRANSFER_COMPLETE 12
|
||||
#define ROSE_CALL_TRANSFER_UPDATE 13
|
||||
#define ROSE_SUBADDRESS_TRANSFER 14
|
||||
/* Q.952 ROSE operations (Diverting) */
|
||||
#define ROSE_DIVERTING_LEG_INFORMATION1 18
|
||||
#define ROSE_DIVERTING_LEG_INFORMATION2 0x15
|
||||
#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_ANFPR_PATHREPLACEMENT 4
|
||||
#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
|
||||
@@ -169,137 +67,111 @@
|
||||
#define Q932_TON_SUBSCRIBER 0x04
|
||||
#define Q932_TON_ABBREVIATED 0x06
|
||||
|
||||
/* RLT related Operations */
|
||||
#define RLT_SERVICE_ID 0x3e
|
||||
#define RLT_OPERATION_IND 0x01
|
||||
#define RLT_THIRD_PARTY 0x02
|
||||
/* Q.SIG Subscription Option. Listed in ECMA-174 */
|
||||
#define QSIG_NO_NOTIFICATION 0x00
|
||||
#define QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR 0x01
|
||||
#define QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR 0x02
|
||||
|
||||
struct rose_component {
|
||||
u_int8_t type;
|
||||
u_int8_t len;
|
||||
u_int8_t data[0];
|
||||
/*! Reasons an APDU callback is called. */
|
||||
enum APDU_CALLBACK_REASON {
|
||||
/*!
|
||||
* \brief Send setup error. Abort and cleanup.
|
||||
* \note The message may or may not actually get sent.
|
||||
* \note The callback cannot generate an event subcmd.
|
||||
* \note The callback should not send messages. Out of order messages will result.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_ERROR,
|
||||
/*!
|
||||
* \brief Abort and cleanup.
|
||||
* \note The APDU queue is being destroyed.
|
||||
* \note The callback cannot generate an event subcmd.
|
||||
* \note The callback cannot send messages as the call is likely being destroyed.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_CLEANUP,
|
||||
/*!
|
||||
* \brief Timeout waiting for responses to the message.
|
||||
* \note The callback can generate an event subcmd.
|
||||
* \note The callback can send messages.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_TIMEOUT,
|
||||
/*!
|
||||
* \brief Received a facility response message.
|
||||
* \note The callback can generate an event subcmd.
|
||||
* \note The callback can send messages.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_MSG_RESULT,
|
||||
/*!
|
||||
* \brief Received a facility error message.
|
||||
* \note The callback can generate an event subcmd.
|
||||
* \note The callback can send messages.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_MSG_ERROR,
|
||||
/*!
|
||||
* \brief Received a facility reject message.
|
||||
* \note The callback can generate an event subcmd.
|
||||
* \note The callback can send messages.
|
||||
*/
|
||||
APDU_CALLBACK_REASON_MSG_REJECT,
|
||||
};
|
||||
|
||||
#if 1
|
||||
#define GET_COMPONENT(component, idx, ptr, length) \
|
||||
if ((idx)+2 > (length)) \
|
||||
break; \
|
||||
(component) = (struct rose_component*)&((ptr)[idx]); \
|
||||
if ((idx)+(component)->len+2 > (length)) { \
|
||||
if ((component)->len != ASN1_LEN_INDEF) \
|
||||
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
|
||||
}
|
||||
#else /* Debugging */
|
||||
#define GET_COMPONENT(component, idx, ptr, length) \
|
||||
if ((idx)+2 > (length)) \
|
||||
break; \
|
||||
(component) = (struct rose_component*)&((ptr)[idx]); \
|
||||
if ((idx)+(component)->len+2 > (length)) { \
|
||||
if ((component)->len != 128) \
|
||||
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
|
||||
} \
|
||||
pri_message(pri, "XX %s:%d Got component %d (0x%02X), length %d\n", __FUNCTION__, __LINE__, (component)->type, (component)->type, (component)->len); \
|
||||
if ((component)->len > 0) { \
|
||||
int zzz; \
|
||||
pri_message(pri, "XX Data:"); \
|
||||
for (zzz = 0; zzz < (component)->len; ++zzz) \
|
||||
pri_message(pri, " %02X", (component)->data[zzz]); \
|
||||
pri_message(pri, "\n"); \
|
||||
}
|
||||
#endif
|
||||
union apdu_msg_data {
|
||||
const struct rose_msg_result *result;
|
||||
const struct rose_msg_error *error;
|
||||
const struct rose_msg_reject *reject;
|
||||
};
|
||||
|
||||
#define NEXT_COMPONENT(component, idx) \
|
||||
(idx) += (component)->len + 2
|
||||
union apdu_callback_param {
|
||||
void *ptr;
|
||||
long value;
|
||||
char pad[8];
|
||||
};
|
||||
|
||||
#define SUB_COMPONENT(component, idx) \
|
||||
(idx) += 2
|
||||
struct apdu_callback_data {
|
||||
/*! APDU invoke id to match with any response messages. (Result/Error/Reject) */
|
||||
int invoke_id;
|
||||
/*!
|
||||
* \brief Time to wait for responses to APDU in ms.
|
||||
* \note Set to 0 if send the message only.
|
||||
* \note Set to less than 0 for PRI_TIMER_T_RESPONSE time.
|
||||
*/
|
||||
int timeout_time;
|
||||
/*!
|
||||
* \brief APDU callback function.
|
||||
*
|
||||
* \param reason Reason callback is called.
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param apdu APDU queued entry. Do not change!
|
||||
* \param msg APDU response message data. (NULL if was not the reason called.)
|
||||
*
|
||||
* \note
|
||||
* A callback must be supplied if the sender cares about any APDU_CALLBACK_REASON.
|
||||
*
|
||||
* \return TRUE if no more responses are expected.
|
||||
*/
|
||||
int (*callback)(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const union apdu_msg_data *msg);
|
||||
/*! \brief Sender data for the callback function to identify the particular APDU. */
|
||||
union apdu_callback_param user;
|
||||
};
|
||||
|
||||
#define CHECK_COMPONENT(component, comptype, message) \
|
||||
if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
|
||||
pri_message(pri, (message), (component)->type); \
|
||||
asn1_dump(pri, (component), (component)->len+2); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#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 ROSE component */
|
||||
int rose_invoke_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
|
||||
|
||||
/* Decoder for the return result ROSE component */
|
||||
int rose_return_result_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
|
||||
|
||||
/* Decoder for the return error ROSE component */
|
||||
int rose_return_error_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
|
||||
|
||||
/* Decoder for the reject ROSE component */
|
||||
int rose_reject_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
|
||||
|
||||
int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
|
||||
|
||||
int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len);
|
||||
|
||||
/* Get Name types from ASN.1 */
|
||||
int asn1_name_decode(void * data, int len, char *namebuf, int buflen);
|
||||
|
||||
int typeofnumber_from_q931(struct pri *pri, int ton);
|
||||
|
||||
int redirectingreason_from_q931(struct pri *pri, int redirectingreason);
|
||||
struct apdu_event {
|
||||
/*! Linked list pointer */
|
||||
struct apdu_event *next;
|
||||
/*! TRUE if this APDU has been sent. */
|
||||
int sent;
|
||||
/*! What message to send the ADPU in */
|
||||
int message;
|
||||
/*! Sender supplied information to handle APDU response messages. */
|
||||
struct apdu_callback_data response;
|
||||
/*! Q.931 call leg. (Needed for the APDU timeout.) */
|
||||
struct q931_call *call;
|
||||
/*! Response timeout timer. */
|
||||
int timer;
|
||||
/*! Length of ADPU */
|
||||
int apdu_len;
|
||||
/*! ADPU to send */
|
||||
unsigned char apdu[255];
|
||||
};
|
||||
|
||||
/* Queues an MWI apdu on a the given call */
|
||||
int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
|
||||
@@ -310,21 +182,31 @@ 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);
|
||||
int send_reroute_request(struct pri *ctrl, q931_call *call, const struct q931_party_id *caller, const struct q931_party_redirecting *deflection, int subscription_option);
|
||||
|
||||
/* starts a QSIG Path Replacement */
|
||||
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,
|
||||
* apdu is the apdu data, apdu_len is the length of the apdu data */
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data);
|
||||
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
|
||||
|
||||
/* Used by q931.c to cleanup the apdu queue upon destruction of a call */
|
||||
int pri_call_apdu_queue_cleanup(q931_call *call);
|
||||
int rose_diverting_leg_information1_encode(struct pri *pri, q931_call *call);
|
||||
int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
|
||||
int rose_connected_name_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
int rose_called_name_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, const unsigned char *apdu, int apdu_len, struct apdu_callback_data *response);
|
||||
void pri_call_apdu_queue_cleanup(q931_call *call);
|
||||
void pri_call_apdu_delete(struct q931_call *call, struct apdu_event *doomed);
|
||||
|
||||
/* Adds the "standard" APDUs to a call */
|
||||
int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
|
||||
|
||||
int asn1_dump(struct pri *pri, void *comp, int len);
|
||||
void asn1_dump(struct pri *ctrl, const unsigned char *start_asn1, const unsigned char *end);
|
||||
|
||||
void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, const struct fac_extension_header *header, const struct rose_msg_invoke *invoke);
|
||||
void rose_handle_result(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, const struct fac_extension_header *header, const struct rose_msg_result *result);
|
||||
void rose_handle_error(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, const struct fac_extension_header *header, const struct rose_msg_error *error);
|
||||
void rose_handle_reject(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, const struct fac_extension_header *header, const struct rose_msg_reject *reject);
|
||||
|
||||
#endif /* _PRI_FACILITY_H */
|
||||
|
||||
611
pri_internal.h
611
pri_internal.h
@@ -32,30 +32,45 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
#include "pri_q921.h"
|
||||
#include "pri_q931.h"
|
||||
|
||||
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define DBGHEAD __FILE__ ":%d %s: "
|
||||
#define DBGINFO __LINE__,__PRETTY_FUNCTION__
|
||||
|
||||
/* Forward declare some structs */
|
||||
struct apdu_event;
|
||||
|
||||
struct pri_sched {
|
||||
struct timeval when;
|
||||
void (*callback)(void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct q921_frame;
|
||||
enum q931_state;
|
||||
enum q931_mode;
|
||||
|
||||
/* No more than 128 scheduled events */
|
||||
/*! Maximum number of scheduled events active at the same time. */
|
||||
#define MAX_SCHED 128
|
||||
|
||||
#define MAX_TIMERS 32
|
||||
/*! Maximum number of facility ie's to handle per incoming message. */
|
||||
#define MAX_FACILITY_IES 8
|
||||
|
||||
/*! Accumulated pri_message() line until a '\n' is seen on the end. */
|
||||
struct pri_msg_line {
|
||||
/*! Accumulated buffer used. */
|
||||
unsigned length;
|
||||
/*! Accumulated pri_message() contents. */
|
||||
char str[2048];
|
||||
};
|
||||
|
||||
/*! \brief D channel controller structure */
|
||||
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;
|
||||
/*! Accumulated pri_message() line. (Valid in master record only) */
|
||||
struct pri_msg_line *msg_line;
|
||||
struct pri *subchannel; /* Sub-channel if appropriate */
|
||||
struct pri *master; /* Master channel if appropriate */
|
||||
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */
|
||||
@@ -71,38 +86,51 @@ struct pri {
|
||||
int protodisc;
|
||||
unsigned int bri:1;
|
||||
unsigned int acceptinbanddisconnect:1; /* Should we allow inband progress after DISCONNECT? */
|
||||
|
||||
unsigned int sendfacility:1;
|
||||
unsigned int overlapdial:1;/* TRUE if we do overlap dialing */
|
||||
unsigned int chan_mapping_logical:1;/* TRUE if do not skip channel 16 (Q.SIG) */
|
||||
unsigned int service_message_support:1;/* TRUE if upper layer supports SERVICE messages */
|
||||
unsigned int hold_support:1;/* TRUE if upper layer supports call hold. */
|
||||
unsigned int deflection_support:1;/* TRUE if upper layer supports call deflection/rerouting. */
|
||||
unsigned int hangup_fix_enabled:1;/* TRUE if should follow Q.931 Section 5.3.2 instead of blindly sending RELEASE_COMPLETE for certain causes */
|
||||
|
||||
/* MDL variables */
|
||||
int mdl_error;
|
||||
int mdl_error_state;
|
||||
int mdl_timer;
|
||||
int mdl_free_me;
|
||||
|
||||
/* Q.921 State */
|
||||
int q921_state;
|
||||
int window; /* Max window size */
|
||||
int windowlen; /* Fullness of window */
|
||||
int RC;
|
||||
int peer_rx_busy:1;
|
||||
int own_rx_busy:1;
|
||||
int acknowledge_pending:1;
|
||||
int reject_exception:1;
|
||||
|
||||
int v_s; /* Next N(S) for transmission */
|
||||
int v_a; /* Last acknowledged frame */
|
||||
int v_r; /* Next frame expected to be received */
|
||||
int v_na; /* What we've told our peer we've acknowledged */
|
||||
int solicitfbit; /* Have we sent an I or S frame with the F-bit set? */
|
||||
int retrans; /* Retransmissions */
|
||||
int sentrej; /* Are we in reject state */
|
||||
|
||||
int cref; /* Next call reference value */
|
||||
|
||||
int busy; /* Peer is busy */
|
||||
int l3initiated;
|
||||
|
||||
/* Various timers */
|
||||
int sabme_timer; /* SABME retransmit */
|
||||
int sabme_count; /* SABME retransmit counter for BRI */
|
||||
int t203_timer; /* Max idle time */
|
||||
int t202_timer;
|
||||
int n202_counter;
|
||||
int ri;
|
||||
int t200_timer; /* T-200 retransmission timer */
|
||||
/* All ISDN Timer values */
|
||||
int timers[MAX_TIMERS];
|
||||
int timers[PRI_MAX_TIMERS];
|
||||
|
||||
/* Used by scheduler */
|
||||
struct timeval tv;
|
||||
int schedev;
|
||||
pri_event ev; /* Static event thingy */
|
||||
/*! Subcommands for static event thingy. */
|
||||
struct pri_subcommands subcmds;
|
||||
|
||||
/* Q.921 Re-transmission queue */
|
||||
struct q921_frame *txqueue;
|
||||
@@ -111,11 +139,12 @@ struct pri {
|
||||
q931_call **callpool;
|
||||
q931_call *localpool;
|
||||
|
||||
/* do we do overlap dialing */
|
||||
int overlapdial;
|
||||
|
||||
/* do not skip channel 16 */
|
||||
int chan_mapping_logical;
|
||||
/*!
|
||||
* \brief Q.931 Dummy call reference call associated with this TEI.
|
||||
* \note If present then this call is allocated as part of the
|
||||
* D channel control structure.
|
||||
*/
|
||||
q931_call *dummy_call;
|
||||
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
/* q921/q931 packet counters */
|
||||
@@ -125,52 +154,226 @@ struct pri {
|
||||
unsigned int q931_rxcount;
|
||||
#endif
|
||||
|
||||
unsigned char last_invoke; /* Last ROSE invoke ID */
|
||||
unsigned char sendfacility;
|
||||
short last_invoke; /* Last ROSE invoke ID (Valid in master record only) */
|
||||
|
||||
/*! For delayed processing of facility ie's. */
|
||||
struct {
|
||||
/*! Array of facility ie locations in the current received message. */
|
||||
q931_ie *ie[MAX_FACILITY_IES];
|
||||
/*! Codeset facility ie found within. */
|
||||
unsigned char codeset[MAX_FACILITY_IES];
|
||||
/*! Number of facility ie's in the array from the current received message. */
|
||||
unsigned char count;
|
||||
} facility;
|
||||
};
|
||||
|
||||
/*! \brief Maximum name length plus null terminator (From ECMA-164) */
|
||||
#define PRI_MAX_NAME_LEN (50 + 1)
|
||||
|
||||
/*! \brief Q.SIG name information. */
|
||||
struct q931_party_name {
|
||||
/*! \brief TRUE if name data is valid */
|
||||
unsigned char valid;
|
||||
/*!
|
||||
* \brief Q.931 presentation-indicator encoded field
|
||||
* \note Must tollerate the Q.931 screening-indicator field values being present.
|
||||
*/
|
||||
unsigned char presentation;
|
||||
/*!
|
||||
* \brief Character set the name is using.
|
||||
* \details
|
||||
* unknown(0),
|
||||
* iso8859-1(1),
|
||||
* enum-value-withdrawn-by-ITU-T(2)
|
||||
* iso8859-2(3),
|
||||
* iso8859-3(4),
|
||||
* iso8859-4(5),
|
||||
* iso8859-5(6),
|
||||
* iso8859-7(7),
|
||||
* iso10646-BmpString(8),
|
||||
* iso10646-utf-8String(9)
|
||||
*/
|
||||
unsigned char char_set;
|
||||
/*! \brief Name data with null terminator. */
|
||||
char str[PRI_MAX_NAME_LEN];
|
||||
};
|
||||
|
||||
/*! \brief Maximum phone number (address) length plus null terminator */
|
||||
#define PRI_MAX_NUMBER_LEN (31 + 1)
|
||||
|
||||
struct q931_party_number {
|
||||
/*! \brief TRUE if number data is valid */
|
||||
unsigned char valid;
|
||||
/*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
|
||||
unsigned char presentation;
|
||||
/*! \brief Q.931 Type-Of-Number and numbering-plan encoded fields */
|
||||
unsigned char plan;
|
||||
/*! \brief Number data with terminator. */
|
||||
char str[PRI_MAX_NUMBER_LEN];
|
||||
};
|
||||
|
||||
/*! \brief Maximum subaddress length plus null terminator */
|
||||
#define PRI_MAX_SUBADDRESS_LEN (20 + 1)
|
||||
|
||||
struct q931_party_subaddress {
|
||||
/*! \brief TRUE if the subaddress information is valid/present */
|
||||
unsigned char valid;
|
||||
/*!
|
||||
* \brief Subaddress type.
|
||||
* \details
|
||||
* nsap(0),
|
||||
* user_specified(2)
|
||||
*/
|
||||
unsigned char type;
|
||||
/*!
|
||||
* \brief TRUE if odd number of address signals
|
||||
* \note The odd/even indicator is used when the type of subaddress is
|
||||
* user_specified and the coding is BCD.
|
||||
*/
|
||||
unsigned char odd_even_indicator;
|
||||
/*! \brief Length of the subaddress data */
|
||||
unsigned char length;
|
||||
/*!
|
||||
* \brief Subaddress data with null terminator.
|
||||
* \note The null terminator is a convenience only since the data could be
|
||||
* BCD/binary and thus have a null byte as part of the contents.
|
||||
*/
|
||||
unsigned char data[PRI_MAX_SUBADDRESS_LEN];
|
||||
};
|
||||
|
||||
struct q931_party_address {
|
||||
/*! \brief Subscriber phone number */
|
||||
struct q931_party_number number;
|
||||
/*! \brief Subscriber subaddress */
|
||||
struct q931_party_subaddress subaddress;
|
||||
};
|
||||
|
||||
/*! \brief Information needed to identify an endpoint in a call. */
|
||||
struct q931_party_id {
|
||||
/*! \brief Subscriber name */
|
||||
struct q931_party_name name;
|
||||
/*! \brief Subscriber phone number */
|
||||
struct q931_party_number number;
|
||||
/*! \brief Subscriber subaddress */
|
||||
struct q931_party_subaddress subaddress;
|
||||
};
|
||||
|
||||
enum Q931_REDIRECTING_STATE {
|
||||
/*!
|
||||
* \details
|
||||
* CDO-Idle/CDF-Inv-Idle
|
||||
*/
|
||||
Q931_REDIRECTING_STATE_IDLE,
|
||||
/*!
|
||||
* \details
|
||||
* CDF-Inv-Wait - A DivLeg2 has been received and
|
||||
* we are waiting for valid presentation restriction information to send.
|
||||
*/
|
||||
Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3,
|
||||
/*!
|
||||
* \details
|
||||
* CDO-Divert - A DivLeg1 has been received and
|
||||
* we are waiting for the presentation restriction information to come in.
|
||||
*/
|
||||
Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3,
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Do not increment above this count.
|
||||
* \details
|
||||
* It is not our responsibility to enforce the maximum number of redirects.
|
||||
* However, we cannot allow an increment past this number without breaking things.
|
||||
* Besides, more than 255 redirects is probably not a good thing.
|
||||
*/
|
||||
#define PRI_MAX_REDIRECTS 0xFF
|
||||
|
||||
/*! \brief Redirecting information struct */
|
||||
struct q931_party_redirecting {
|
||||
enum Q931_REDIRECTING_STATE state;
|
||||
/*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */
|
||||
struct q931_party_id from;
|
||||
/*! \brief Call is redirecting to a new party (Sent to the caller) */
|
||||
struct q931_party_id to;
|
||||
/*! Originally called party (in cases of multiple redirects) */
|
||||
struct q931_party_id orig_called;
|
||||
/*!
|
||||
* \brief Number of times the call was redirected
|
||||
* \note The call is being redirected if the count is non-zero.
|
||||
*/
|
||||
unsigned char count;
|
||||
/*! Original reason for redirect (in cases of multiple redirects) */
|
||||
unsigned char orig_reason;
|
||||
/*! \brief Redirection reasons */
|
||||
unsigned char reason;
|
||||
};
|
||||
|
||||
/*! \brief New call setup parameter structure */
|
||||
struct pri_sr {
|
||||
int transmode;
|
||||
int channel;
|
||||
int exclusive;
|
||||
int nonisdn;
|
||||
char *caller;
|
||||
int callerplan;
|
||||
char *callername;
|
||||
int callerpres;
|
||||
char *called;
|
||||
int calledplan;
|
||||
struct q931_party_redirecting redirecting;
|
||||
struct q931_party_id caller;
|
||||
struct q931_party_address called;
|
||||
int userl1;
|
||||
int numcomplete;
|
||||
char *redirectingnum;
|
||||
int redirectingplan;
|
||||
int redirectingpres;
|
||||
int redirectingreason;
|
||||
int justsignalling;
|
||||
int cis_call;
|
||||
int cis_auto_disconnect;
|
||||
const char *useruserinfo;
|
||||
const char *keypad_digits;
|
||||
int transferable;
|
||||
int reversecharge;
|
||||
};
|
||||
|
||||
/* Internal switch types */
|
||||
#define PRI_SWITCH_GR303_EOC_PATH 19
|
||||
#define PRI_SWITCH_GR303_TMC_SWITCHING 20
|
||||
|
||||
struct apdu_event {
|
||||
int message; /* What message to send the ADPU in */
|
||||
void (*callback)(void *data); /* Callback function for when response is received */
|
||||
void *data; /* Data to callback */
|
||||
unsigned char apdu[255]; /* ADPU to send */
|
||||
int apdu_len; /* Length of ADPU */
|
||||
int sent; /* Have we been sent already? */
|
||||
struct apdu_event *next; /* Linked list pointer */
|
||||
#define Q931_MAX_TEI 8
|
||||
|
||||
/*! \brief Incoming call transfer states. */
|
||||
enum INCOMING_CT_STATE {
|
||||
/*!
|
||||
* \details
|
||||
* Incoming call transfer is not active.
|
||||
*/
|
||||
INCOMING_CT_STATE_IDLE,
|
||||
/*!
|
||||
* \details
|
||||
* We have seen an incoming CallTransferComplete(alerting)
|
||||
* so we are waiting for the expected CallTransferActive
|
||||
* before updating the connected line about the remote party id.
|
||||
*/
|
||||
INCOMING_CT_STATE_EXPECT_CT_ACTIVE,
|
||||
/*!
|
||||
* \details
|
||||
* A call transfer message came in that updated the remote party id
|
||||
* that we need to post a connected line update.
|
||||
*/
|
||||
INCOMING_CT_STATE_POST_CONNECTED_LINE
|
||||
};
|
||||
|
||||
/*! Call hold supplementary states. */
|
||||
enum Q931_HOLD_STATE {
|
||||
/*! \brief No call hold activity. */
|
||||
Q931_HOLD_STATE_IDLE,
|
||||
/*! \brief Request made to hold call. */
|
||||
Q931_HOLD_STATE_HOLD_REQ,
|
||||
/*! \brief Request received to hold call. */
|
||||
Q931_HOLD_STATE_HOLD_IND,
|
||||
/*! \brief Call is held. */
|
||||
Q931_HOLD_STATE_CALL_HELD,
|
||||
/*! \brief Request made to retrieve call. */
|
||||
Q931_HOLD_STATE_RETRIEVE_REQ,
|
||||
/*! \brief Request received to retrieve call. */
|
||||
Q931_HOLD_STATE_RETRIEVE_IND,
|
||||
};
|
||||
|
||||
/* 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;
|
||||
@@ -199,71 +402,142 @@ struct q931_call {
|
||||
int userl2;
|
||||
int userl3;
|
||||
int rateadaption;
|
||||
|
||||
int sentchannel;
|
||||
int justsignalling; /* for a signalling-only connection */
|
||||
|
||||
/*!
|
||||
* \brief TRUE if the call is a Call Independent Signalling connection.
|
||||
* \note The call has no B channel associated with it. (Just signalling)
|
||||
*/
|
||||
int cis_call;
|
||||
/*! \brief TRUE if we will auto disconnect the cis_call we originated. */
|
||||
int cis_auto_disconnect;
|
||||
|
||||
int progcode; /* Progress coding */
|
||||
int progloc; /* Progress Location */
|
||||
int progress; /* Progress indicator */
|
||||
int progressmask; /* Progress Indicator bitmask */
|
||||
|
||||
int notify; /* Notification */
|
||||
int notify; /* Notification indicator. */
|
||||
|
||||
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 keypad_digits[64]; /* Buffer for digits that come in KEYPAD_FACILITY */
|
||||
enum Q931_CALL_STATE peercallstate; /* Call state of peer as reported */
|
||||
enum Q931_CALL_STATE ourcallstate; /* Our call state */
|
||||
enum Q931_CALL_STATE sugcallstate; /* Status call state */
|
||||
|
||||
int ani2; /* ANI II */
|
||||
|
||||
int calledplan;
|
||||
|
||||
/*! Buffer for digits that come in KEYPAD_FACILITY */
|
||||
char keypad_digits[32 + 1];
|
||||
|
||||
/*! Current dialed digits to be sent or just received. */
|
||||
char overlap_digits[PRI_MAX_NUMBER_LEN];
|
||||
|
||||
/*!
|
||||
* \brief Local party ID
|
||||
* \details
|
||||
* The Caller-ID and connected-line ID are just roles the local and remote party
|
||||
* play while a call is being established. Which roll depends upon the direction
|
||||
* of the call.
|
||||
* Outgoing party info is to identify the local party to the other end.
|
||||
* (Caller-ID for originated or connected-line for answered calls.)
|
||||
* Incoming party info is to identify the remote party to us.
|
||||
* (Caller-ID for answered or connected-line for originated calls.)
|
||||
*/
|
||||
struct q931_party_id local_id;
|
||||
/*!
|
||||
* \brief Remote party ID
|
||||
* \details
|
||||
* The Caller-ID and connected-line ID are just roles the local and remote party
|
||||
* play while a call is being established. Which roll depends upon the direction
|
||||
* of the call.
|
||||
* Outgoing party info is to identify the local party to the other end.
|
||||
* (Caller-ID for originated or connected-line for answered calls.)
|
||||
* Incoming party info is to identify the remote party to us.
|
||||
* (Caller-ID for answered or connected-line for originated calls.)
|
||||
*/
|
||||
struct q931_party_id remote_id;
|
||||
|
||||
/*!
|
||||
* \brief Staging place for the Q.931 redirection number ie.
|
||||
* \note
|
||||
* The number could be the remote_id.number or redirecting.to.number
|
||||
* depending upon the notification indicator.
|
||||
*/
|
||||
struct q931_party_number redirection_number;
|
||||
|
||||
/*!
|
||||
* \brief Called party address.
|
||||
* \note The called.number.str is the accumulated overlap dial digits
|
||||
* and enbloc digits.
|
||||
* \note The called.number.presentation value is not used.
|
||||
*/
|
||||
struct q931_party_address called;
|
||||
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 */
|
||||
struct q931_party_redirecting redirecting;
|
||||
|
||||
/* 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 */
|
||||
/*! \brief Incoming call transfer state. */
|
||||
enum INCOMING_CT_STATE incoming_ct_state;
|
||||
/*! Call hold supplementary state. */
|
||||
enum Q931_HOLD_STATE hold_state;
|
||||
/*! Call hold event timer */
|
||||
int hold_timer;
|
||||
|
||||
int deflection_in_progress; /*!< CallDeflection for NT PTMP in progress. */
|
||||
/*! TRUE if the connected number ie was in the current received message. */
|
||||
int connected_number_in_message;
|
||||
/*! TRUE if the redirecting number ie was in the current received message. */
|
||||
int redirecting_number_in_message;
|
||||
|
||||
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 */
|
||||
|
||||
int transferable;
|
||||
int transferable; /* RLT call is transferable */
|
||||
unsigned int rlt_call_id; /* RLT call id */
|
||||
|
||||
/* Bridged call info */
|
||||
q931_call *bridged_call; /* Pointer to other leg of bridged call */
|
||||
q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
|
||||
|
||||
int changestatus; /* SERVICE message changestatus */
|
||||
int reversecharge; /* Reverse charging indication:
|
||||
-1 - No reverse charging
|
||||
1 - Reverse charging
|
||||
0,2-7 - Reserved for future use */
|
||||
int t303_timer;
|
||||
int t303_expirycnt;
|
||||
|
||||
int hangupinitiated;
|
||||
/*! \brief TRUE if we broadcast this call's SETUP message. */
|
||||
int outboundbroadcast;
|
||||
int performing_fake_clearing;
|
||||
/*!
|
||||
* \brief Master call controlling this call.
|
||||
* \note Always valid. Master and normal calls point to self.
|
||||
*/
|
||||
struct q931_call *master_call;
|
||||
|
||||
/* These valid in master call only */
|
||||
struct q931_call *subcalls[Q931_MAX_TEI];
|
||||
int pri_winner;
|
||||
};
|
||||
|
||||
/*! D channel control structure with associated dummy call reference record. */
|
||||
struct d_ctrl_dummy {
|
||||
/*! D channel control structure. Must be first in the structure. */
|
||||
struct pri ctrl;
|
||||
/*! Dummy call reference call record. */
|
||||
struct q931_call dummy_call;
|
||||
};
|
||||
|
||||
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
|
||||
@@ -274,14 +548,187 @@ extern void pri_schedule_del(struct pri *pri, int ev);
|
||||
|
||||
extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
|
||||
|
||||
extern void pri_message(struct pri *pri, char *fmt, ...);
|
||||
|
||||
extern void pri_error(struct pri *pri, char *fmt, ...);
|
||||
void pri_message(struct pri *ctrl, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
void pri_error(struct pri *ctrl, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
void libpri_copy_string(char *dst, const char *src, size_t size);
|
||||
|
||||
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri);
|
||||
|
||||
void __pri_free_tei(struct pri *p);
|
||||
|
||||
void q931_init_call_record(struct pri *ctrl, struct q931_call *call, int cr);
|
||||
|
||||
void q931_party_name_init(struct q931_party_name *name);
|
||||
void q931_party_number_init(struct q931_party_number *number);
|
||||
void q931_party_subaddress_init(struct q931_party_subaddress *subaddr);
|
||||
void q931_party_address_init(struct q931_party_address *address);
|
||||
void q931_party_id_init(struct q931_party_id *id);
|
||||
void q931_party_redirecting_init(struct q931_party_redirecting *redirecting);
|
||||
|
||||
static inline void q931_party_address_to_id(struct q931_party_id *id, struct q931_party_address *address)
|
||||
{
|
||||
id->number = address->number;
|
||||
id->subaddress = address->subaddress;
|
||||
}
|
||||
|
||||
int q931_party_name_cmp(const struct q931_party_name *left, const struct q931_party_name *right);
|
||||
int q931_party_number_cmp(const struct q931_party_number *left, const struct q931_party_number *right);
|
||||
int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right);
|
||||
int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_id *right);
|
||||
|
||||
void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q931_party_name *q931_name);
|
||||
void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const struct q931_party_number *q931_number);
|
||||
void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress);
|
||||
void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_party_id *q931_id);
|
||||
void q931_party_redirecting_copy_to_pri(struct pri_party_redirecting *pri_redirecting, const struct q931_party_redirecting *q931_redirecting);
|
||||
|
||||
void pri_copy_party_name_to_q931(struct q931_party_name *q931_name, const struct pri_party_name *pri_name);
|
||||
void pri_copy_party_number_to_q931(struct q931_party_number *q931_number, const struct pri_party_number *pri_number);
|
||||
void pri_copy_party_subaddress_to_q931(struct q931_party_subaddress *q931_subaddress, const struct pri_party_subaddress *pri_subaddress);
|
||||
void pri_copy_party_id_to_q931(struct q931_party_id *q931_id, const struct pri_party_id *pri_id);
|
||||
|
||||
void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id);
|
||||
int q931_party_id_presentation(const struct q931_party_id *id);
|
||||
|
||||
const char *q931_call_state_str(enum Q931_CALL_STATE callstate);
|
||||
const char *msg2str(int msg);
|
||||
|
||||
int q931_master_pass_event(struct pri *ctrl, struct q931_call *subcall, int msg_type);
|
||||
struct pri_subcommand *q931_alloc_subcommand(struct pri *ctrl);
|
||||
|
||||
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
|
||||
|
||||
/*!
|
||||
* \brief Get the master PRI control structure.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Master PRI control structure.
|
||||
*/
|
||||
static inline struct pri *PRI_MASTER(struct pri *ctrl)
|
||||
{
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in BRI NT PTMP mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in BRI NT PTMP mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int BRI_NT_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_NETWORK
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in BRI TE PTMP mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in BRI TE PTMP mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int BRI_TE_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_CPE
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in NT mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in NT mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int NT_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->localtype == PRI_NETWORK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in TE mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in TE mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int TE_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->localtype == PRI_CPE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in PTP mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in PTP mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int PTP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_PRI;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in PTMP mode.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \retval TRUE if in PTMP mode.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int PTMP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
#define Q931_DUMMY_CALL_REFERENCE -1
|
||||
#define Q931_CALL_REFERENCE_FLAG 0x8000 /* Identify which end allocted the CR. */
|
||||
|
||||
/*!
|
||||
* \brief Deterimine if the given call control pointer is a dummy call.
|
||||
*
|
||||
* \retval TRUE if given call is a dummy call.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int q931_is_dummy_call(const q931_call *call)
|
||||
{
|
||||
return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
37
pri_q921.h
37
pri_q921.h
@@ -166,30 +166,41 @@ typedef struct q921_frame {
|
||||
} q921_frame;
|
||||
|
||||
#define Q921_INC(j) (j) = (((j) + 1) % 128)
|
||||
#define Q921_DEC(j) (j) = (((j) - 1) % 128)
|
||||
|
||||
typedef enum q921_state {
|
||||
Q921_DOWN = 0,
|
||||
Q921_TEI_UNASSIGNED,
|
||||
Q921_TEI_AWAITING_ESTABLISH,
|
||||
Q921_TEI_AWAITING_ASSIGN,
|
||||
Q921_TEI_ASSIGNED,
|
||||
Q921_NEGOTIATION,
|
||||
Q921_LINK_CONNECTION_RELEASED, /* Also known as TEI_ASSIGNED */
|
||||
Q921_LINK_CONNECTION_ESTABLISHED,
|
||||
Q921_AWAITING_ESTABLISH,
|
||||
Q921_AWAITING_RELEASE
|
||||
/* All states except Q921_DOWN are defined in Q.921 SDL diagrams */
|
||||
Q921_TEI_UNASSIGNED = 1,
|
||||
Q921_ASSIGN_AWAITING_TEI = 2,
|
||||
Q921_ESTABLISH_AWAITING_TEI = 3,
|
||||
Q921_TEI_ASSIGNED = 4,
|
||||
Q921_AWAITING_ESTABLISHMENT = 5,
|
||||
Q921_AWAITING_RELEASE = 6,
|
||||
Q921_MULTI_FRAME_ESTABLISHED = 7,
|
||||
Q921_TIMER_RECOVERY = 8,
|
||||
} q921_state;
|
||||
|
||||
static inline int Q921_ADD(int a, int b)
|
||||
{
|
||||
return (a + b) % 128;
|
||||
}
|
||||
|
||||
/* Dumps a *known good* Q.921 packet */
|
||||
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_start(struct pri *pri);
|
||||
|
||||
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);
|
||||
|
||||
extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr);
|
||||
extern int q921_transmit_iframe(struct pri *pri, int tei, void *buf, int len, int cr);
|
||||
|
||||
extern int q921_transmit_uiframe(struct pri *pri, void *buf, int len);
|
||||
|
||||
extern pri_event *q921_dchannel_up(struct pri *pri);
|
||||
|
||||
//extern pri_event *q921_dchannel_down(struct pri *pri);
|
||||
|
||||
#endif
|
||||
|
||||
349
pri_q931.h
349
pri_q931.h
@@ -30,44 +30,6 @@
|
||||
#ifndef _PRI_Q931_H
|
||||
#define _PRI_Q931_H
|
||||
|
||||
typedef enum q931_state {
|
||||
/* User states */
|
||||
U0_NULL_STATE,
|
||||
U1_CALL_INITIATED,
|
||||
U2_OVERLAP_SENDING,
|
||||
U3_OUTGOING_CALL_PROCEEDING,
|
||||
U4_CALL_DELIVERED,
|
||||
U6_CALL_PRESENT,
|
||||
U7_CALL_RECEIVED,
|
||||
U8_CONNECT_REQUEST,
|
||||
U9_INCOMING_CALL_PROCEEDING,
|
||||
U10_ACTIVE,
|
||||
U11_DISCONNECT_REQUEST,
|
||||
U12_DISCONNECT_INDICATION,
|
||||
U15_SUSPEND_REQUEST,
|
||||
U17_RESUME_REQUEST,
|
||||
U19_RELEASE_REQUEST,
|
||||
U25_OVERLAP_RECEIVING,
|
||||
/* Network states */
|
||||
N0_NULL_STATE,
|
||||
N1_CALL_INITIATED,
|
||||
N2_OVERLAP_SENDING,
|
||||
N3_OUTGOING_CALL_PROCEEDING,
|
||||
N4_CALL_DELIVERED,
|
||||
N6_CALL_PRESENT,
|
||||
N7_CALL_RECEIVED,
|
||||
N8_CONNECT_REQUEST,
|
||||
N9_INCOMING_CALL_PROCEEDING,
|
||||
N10_ACTIVE,
|
||||
N11_DISCONNECT_REQUEST,
|
||||
N12_DISCONNECT_INDICATION,
|
||||
N15_SUSPEND_REQUEST,
|
||||
N17_RESUME_REQUEST,
|
||||
N19_RELEASE_REQUEST,
|
||||
N22_CALL_ABORT,
|
||||
N25_OVERLAP_RECEIVING
|
||||
} q931_state;
|
||||
|
||||
typedef enum q931_mode {
|
||||
UNKNOWN_MODE,
|
||||
CIRCUIT_MODE,
|
||||
@@ -79,13 +41,13 @@ typedef struct q931_h {
|
||||
u_int8_t pd; /* Protocol Discriminator */
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
u_int8_t x0:4;
|
||||
u_int8_t crlen:4;
|
||||
u_int8_t crlen:4;/*!< Call reference length */
|
||||
#else
|
||||
u_int8_t crlen:4;
|
||||
u_int8_t crlen:4;/*!< Call reference length */
|
||||
u_int8_t x0:4;
|
||||
#endif
|
||||
u_int8_t contents[0];
|
||||
u_int8_t crv[3];
|
||||
u_int8_t crv[3];/*!< Call reference value */
|
||||
} __attribute__ ((packed)) q931_h;
|
||||
|
||||
|
||||
@@ -113,6 +75,10 @@ typedef struct q931_ie {
|
||||
|
||||
#define Q931_PROTOCOL_DISCRIMINATOR 0x08
|
||||
#define GR303_PROTOCOL_DISCRIMINATOR 0x4f
|
||||
/* AT&T Maintenance Protocol Discriminator */
|
||||
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_1 0x03
|
||||
/* National Maintenance Protocol Discriminator */
|
||||
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_2 0x43
|
||||
|
||||
/* Q.931 / National ISDN Message Types */
|
||||
|
||||
@@ -157,8 +123,16 @@ typedef struct q931_ie {
|
||||
#define Q931_SUSPEND_REJECT 0x21
|
||||
|
||||
/* Maintenance messages (codeset 0 only) */
|
||||
#define NATIONAL_SERVICE 0x0f
|
||||
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x07
|
||||
#define ATT_SERVICE 0x0f
|
||||
#define ATT_SERVICE_ACKNOWLEDGE 0x07
|
||||
#define NATIONAL_SERVICE 0x07
|
||||
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x0f
|
||||
|
||||
#define SERVICE_CHANGE_STATUS_INSERVICE 0
|
||||
#define SERVICE_CHANGE_STATUS_LOOPBACK 1 /* not supported */
|
||||
#define SERVICE_CHANGE_STATUS_OUTOFSERVICE 2
|
||||
#define SERVICE_CHANGE_STATUS_REQCONTINUITYCHECK 3 /* not supported */
|
||||
#define SERVICE_CHANGE_STATUS_SHUTDOWN 4 /* not supported */
|
||||
|
||||
/* Special codeset 0 IE */
|
||||
#define NATIONAL_CHANGE_STATUS 0x1
|
||||
@@ -168,10 +142,11 @@ typedef struct q931_ie {
|
||||
#define Q931_NON_LOCKING_SHIFT 0x98
|
||||
#define Q931_BEARER_CAPABILITY 0x04
|
||||
#define Q931_CAUSE 0x08
|
||||
#define Q931_CALL_STATE 0x14
|
||||
#define Q931_IE_CALL_STATE 0x14
|
||||
#define Q931_CHANNEL_IDENT 0x18
|
||||
#define Q931_PROGRESS_INDICATOR 0x1e
|
||||
#define Q931_NETWORK_SPEC_FAC 0x20
|
||||
#define Q931_CALLING_PARTY_CATEGORY (0x32 | Q931_CODESET(5))
|
||||
#define Q931_INFORMATION_RATE 0x40
|
||||
#define Q931_TRANSIT_DELAY 0x42
|
||||
#define Q931_TRANS_DELAY_SELECT 0x43
|
||||
@@ -200,8 +175,9 @@ typedef struct q931_ie {
|
||||
#define Q931_IE_SEGMENTED_MSG 0x00
|
||||
#define Q931_IE_CHANGE_STATUS 0x01
|
||||
#define Q931_IE_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
|
||||
#define Q931_IE_CONNECTED_ADDR 0x0C
|
||||
#define Q931_IE_CONNECTED_NUM 0x4C
|
||||
#define Q931_IE_CONNECTED_ADDR 0x0c
|
||||
#define Q931_IE_CONNECTED_NUM 0x4c
|
||||
#define Q931_IE_CONNECTED_SUBADDR 0x4d
|
||||
#define Q931_IE_CALL_IDENTITY 0x10
|
||||
#define Q931_IE_FACILITY 0x1c
|
||||
#define Q931_IE_ENDPOINT_ID 0x26
|
||||
@@ -224,35 +200,259 @@ typedef struct q931_ie {
|
||||
#define Q931_IE_ESCAPE_FOR_EXT 0x7F
|
||||
|
||||
|
||||
/* Call state stuff */
|
||||
#define Q931_CALL_STATE_NULL 0
|
||||
#define Q931_CALL_STATE_CALL_INITIATED 1
|
||||
#define Q931_CALL_STATE_OVERLAP_SENDING 2
|
||||
#define Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING 3
|
||||
#define Q931_CALL_STATE_CALL_DELIVERED 4
|
||||
#define Q931_CALL_STATE_CALL_PRESENT 6
|
||||
#define Q931_CALL_STATE_CALL_RECEIVED 7
|
||||
#define Q931_CALL_STATE_CONNECT_REQUEST 8
|
||||
#define Q931_CALL_STATE_INCOMING_CALL_PROCEEDING 9
|
||||
#define Q931_CALL_STATE_ACTIVE 10
|
||||
#define Q931_CALL_STATE_DISCONNECT_REQUEST 11
|
||||
#define Q931_CALL_STATE_DISCONNECT_INDICATION 12
|
||||
#define Q931_CALL_STATE_SUSPEND_REQUEST 15
|
||||
#define Q931_CALL_STATE_RESUME_REQUEST 17
|
||||
#define Q931_CALL_STATE_RELEASE_REQUEST 19
|
||||
#define Q931_CALL_STATE_OVERLAP_RECEIVING 25
|
||||
#define Q931_CALL_STATE_RESTART_REQUEST 61
|
||||
#define Q931_CALL_STATE_RESTART 62
|
||||
/*! Q.931 call states */
|
||||
enum Q931_CALL_STATE {
|
||||
/*!
|
||||
* \details
|
||||
* null state (U0):
|
||||
* No call exists.
|
||||
* \details
|
||||
* null state (N0):
|
||||
* No call exists.
|
||||
*/
|
||||
Q931_CALL_STATE_NULL = 0,
|
||||
/*!
|
||||
* \details
|
||||
* call initiated (U1):
|
||||
* This state exists for an outgoing call, when the user requests
|
||||
* call establishment from the network.
|
||||
* \details
|
||||
* call initiated (N1):
|
||||
* This state exists for an outgoing call when the network has received
|
||||
* a call establishment request but has not yet responded.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_INITIATED = 1,
|
||||
/*!
|
||||
* \details
|
||||
* overlap sending (U2):
|
||||
* This state exists for an outgoing call when the user has
|
||||
* received acknowledgement of the call establishment request which
|
||||
* permits the user to send additional call information to the network
|
||||
* in overlap mode.
|
||||
* \details
|
||||
* overlap sending (N2):
|
||||
* This state exists for an outgoing call when the network has acknowledged
|
||||
* the call establishment request and is prepared to receive additional
|
||||
* call information (if any) in overlap mode.
|
||||
*/
|
||||
Q931_CALL_STATE_OVERLAP_SENDING = 2,
|
||||
/*!
|
||||
* \details
|
||||
* outgoing call proceeding (U3):
|
||||
* This state exists for an outgoing call when the user has
|
||||
* received acknowledgement that the network has received all
|
||||
* call information necessary to effect call establishment.
|
||||
* \details
|
||||
* outgoing call proceeding (N3):
|
||||
* This state exists for an outgoing call when the network has sent
|
||||
* acknowledgement that the network has received all call information
|
||||
* necessary to effect call establishment.
|
||||
*/
|
||||
Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING = 3,
|
||||
/*!
|
||||
* \details
|
||||
* call delivered (U4):
|
||||
* This state exists for an outgoing call when the calling user has
|
||||
* received an indication that remote user alerting has been initiated.
|
||||
* \details
|
||||
* call delivered (N4):
|
||||
* This state exists for an outgoing call when the network has indicated
|
||||
* that remote user alerting has been initiated.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_DELIVERED = 4,
|
||||
/*!
|
||||
* \details
|
||||
* call present (U6):
|
||||
* This state exists for an incoming call when the user has received a
|
||||
* call establishment request but has not yet responded.
|
||||
* \details
|
||||
* call present (N6):
|
||||
* This state exists for an incoming call when the network has sent a
|
||||
* call establishment request but has not yet received a satisfactory
|
||||
* response.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_PRESENT = 6,
|
||||
/*!
|
||||
* \details
|
||||
* call received (U7):
|
||||
* This state exists for an incoming call when the user has indicated
|
||||
* alerting but has not yet answered.
|
||||
* \details
|
||||
* call received (N7):
|
||||
* This state exists for an incoming call when the network has received
|
||||
* an indication that the user is alerting but has not yet received an
|
||||
* answer.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_RECEIVED = 7,
|
||||
/*!
|
||||
* \details
|
||||
* connect request (U8):
|
||||
* This state exists for an incoming call when the user has answered
|
||||
* the call and is waiting to be awarded the call.
|
||||
* \details
|
||||
* connect request (N8):
|
||||
* This state exists for an incoming call when the network has received
|
||||
* an answer but the network has not yet awarded the call.
|
||||
*/
|
||||
Q931_CALL_STATE_CONNECT_REQUEST = 8,
|
||||
/*!
|
||||
* \details
|
||||
* incoming call proceeding (U9):
|
||||
* This state exists for an incoming call when the user has sent
|
||||
* acknowledgement that the user has received all call information
|
||||
* necessary to effect call establishment.
|
||||
* \details
|
||||
* incoming call proceeding (N9):
|
||||
* This state exists for an incoming call when the network has received
|
||||
* acknowledgement that the user has received all call information
|
||||
* necessary to effect call establishment.
|
||||
*/
|
||||
Q931_CALL_STATE_INCOMING_CALL_PROCEEDING = 9,
|
||||
/*!
|
||||
* \details
|
||||
* active (U10):
|
||||
* This state exists for an incoming call when the user has received
|
||||
* an acknowledgement from the network that the user has been awarded
|
||||
* the call. This state exists for an outgoing call when the user has
|
||||
* received an indication that the remote user has answered the call.
|
||||
* \details
|
||||
* active (N10):
|
||||
* This state exists for an incoming call when the network has awarded
|
||||
* the call to the called user. This state exists for an outgoing call
|
||||
* when the network has indicated that the remote user has answered
|
||||
* the call.
|
||||
*/
|
||||
Q931_CALL_STATE_ACTIVE = 10,
|
||||
/*!
|
||||
* \details
|
||||
* disconnect request (U11):
|
||||
* This state exists when the user has requested the network to clear
|
||||
* the end-to-end connection (if any) and is waiting for a response.
|
||||
* \details
|
||||
* disconnect request (N11):
|
||||
* This state exists when the network has received a request from the
|
||||
* user to clear the end-to-end connection (if any).
|
||||
*/
|
||||
Q931_CALL_STATE_DISCONNECT_REQUEST = 11,
|
||||
/*!
|
||||
* \details
|
||||
* disconnect indication (U12):
|
||||
* This state exists when the user has received an invitation to
|
||||
* disconnect because the network has disconnected the end-to-end
|
||||
* connection (if any).
|
||||
* \details
|
||||
* disconnect indication (N12):
|
||||
* This state exists when the network has disconnected the end-to-end
|
||||
* connection (if any) and has sent an invitation to disconnect the
|
||||
* user-network connection.
|
||||
*/
|
||||
Q931_CALL_STATE_DISCONNECT_INDICATION = 12,
|
||||
/*!
|
||||
* \details
|
||||
* suspend request (U15):
|
||||
* This state exists when the user has requested the network to suspend
|
||||
* the call and is waiting for a response.
|
||||
* \details
|
||||
* suspend request (N15):
|
||||
* This state exists when the network has received a request to suspend
|
||||
* the call but has not yet responded.
|
||||
*/
|
||||
Q931_CALL_STATE_SUSPEND_REQUEST = 15,
|
||||
/*!
|
||||
* \details
|
||||
* resume request (U17):
|
||||
* This state exists when the user has requested the network to resume
|
||||
* a previously suspended call and is waiting for a response.
|
||||
* \details
|
||||
* resume request (N17):
|
||||
* This state exists when the network has received a request to resume
|
||||
* a previously suspended call but has not yet responded.
|
||||
*/
|
||||
Q931_CALL_STATE_RESUME_REQUEST = 17,
|
||||
/*!
|
||||
* \details
|
||||
* release request (U19):
|
||||
* This state exists when the user has requested the network to release
|
||||
* and is waiting for a response.
|
||||
* \details
|
||||
* release request (N19):
|
||||
* This state exists when the network has requested the user to release
|
||||
* and is waiting for a response.
|
||||
*/
|
||||
Q931_CALL_STATE_RELEASE_REQUEST = 19,
|
||||
/*!
|
||||
* \details
|
||||
* call abort (N22):
|
||||
* This state exists for an incoming call for the point-to-multipoint
|
||||
* configuration when the call is being cleared before any user has been
|
||||
* awarded the call.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_ABORT = 22,
|
||||
/*!
|
||||
* \details
|
||||
* overlap receiving (U25):
|
||||
* This state exists for an incoming call when the user has acknowledged
|
||||
* the call establishment request from the network and is prepared to
|
||||
* receive additional call information (if any) in overlap mode.
|
||||
* \details
|
||||
* overlap receiving (N25):
|
||||
* This state exists for an incoming call when the network has received
|
||||
* acknowledgement of the call establishment request which permits the
|
||||
* network to send additional call information (if any) in the overlap
|
||||
* mode.
|
||||
*/
|
||||
Q931_CALL_STATE_OVERLAP_RECEIVING = 25,
|
||||
/*!
|
||||
* \details
|
||||
* call independent service (U31): (From Q.932)
|
||||
* This state exists when a call independent supplementary service
|
||||
* signalling connection is established.
|
||||
* \details
|
||||
* call independent service (N31): (From Q.932)
|
||||
* This state exists when a call independent supplementary service
|
||||
* signalling connection is established.
|
||||
*/
|
||||
Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE = 31,
|
||||
Q931_CALL_STATE_RESTART_REQUEST = 61,
|
||||
Q931_CALL_STATE_RESTART = 62,
|
||||
/*!
|
||||
* \details
|
||||
* Call state has not been set.
|
||||
* Call state does not exist.
|
||||
* Call state not initialized.
|
||||
* Call state internal use only.
|
||||
*/
|
||||
Q931_CALL_STATE_NOT_SET = 0xFF,
|
||||
};
|
||||
|
||||
/*! Q.931 call establishment state ranking for competing calls in PTMP NT mode. */
|
||||
enum Q931_RANKED_CALL_STATE {
|
||||
/*! Call is present but has no response yet. */
|
||||
Q931_RANKED_CALL_STATE_PRESENT,
|
||||
/*! Call is collecting digits. */
|
||||
Q931_RANKED_CALL_STATE_OVERLAP,
|
||||
/*! Call routing is happening. */
|
||||
Q931_RANKED_CALL_STATE_PROCEEDING,
|
||||
/*! Called party is being alerted of the call. */
|
||||
Q931_RANKED_CALL_STATE_ALERTING,
|
||||
/*! Call is connected. A winner has been declared. */
|
||||
Q931_RANKED_CALL_STATE_CONNECT,
|
||||
/*! Call is in some non-call establishment state (likely disconnecting). */
|
||||
Q931_RANKED_CALL_STATE_OTHER,
|
||||
};
|
||||
|
||||
/* EuroISDN */
|
||||
#define Q931_SENDING_COMPLETE 0xa1
|
||||
|
||||
extern int maintenance_service(struct pri *pri, int span, int channel, int changestatus);
|
||||
|
||||
extern int maintenance_service_ack(struct pri *pri, q931_call *call);
|
||||
|
||||
|
||||
/* Q.SIG specific */
|
||||
#define QSIG_IE_TRANSIT_COUNT 0x31
|
||||
|
||||
extern int q931_receive(struct pri *pri, q931_h *h, int len);
|
||||
extern int q931_receive(struct pri *pri, int tei, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
@@ -268,7 +468,7 @@ extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int non
|
||||
|
||||
extern int q931_information(struct pri *pri, q931_call *call, char digit);
|
||||
|
||||
extern int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits);
|
||||
extern int q931_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
||||
|
||||
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
|
||||
@@ -286,13 +486,22 @@ extern int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode);
|
||||
|
||||
extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
|
||||
|
||||
extern q931_call *q931_new_call(struct pri *pri);
|
||||
struct q931_call *q931_find_call(struct pri *ctrl, int cr);
|
||||
struct 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(struct pri *pri, q931_h *h, int len, int txrx);
|
||||
void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
|
||||
|
||||
extern void __q931_destroycall(struct pri *pri, q931_call *c);
|
||||
void q931_destroycall(struct pri *pri, q931_call *c);
|
||||
|
||||
extern void q931_dl_indication(struct pri *pri, int event);
|
||||
|
||||
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_send_hold_rej(struct pri *ctrl, struct q931_call *call, int cause);
|
||||
|
||||
int q931_send_retrieve(struct pri *ctrl, struct q931_call *call, int channel);
|
||||
int q931_send_retrieve_ack(struct pri *ctrl, struct q931_call *call, int channel);
|
||||
int q931_send_retrieve_rej(struct pri *ctrl, struct q931_call *call, int cause);
|
||||
|
||||
#endif
|
||||
|
||||
97
pri_timers.h
97
pri_timers.h
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* Copyright (C) 2001, Digium, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
#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 */ \
|
||||
3, /* N202 */ \
|
||||
7, /* K */ \
|
||||
1000, /* T200 */ \
|
||||
-1, /* T201 */ \
|
||||
10000, /* 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 */ \
|
||||
2500, /* TM20 - Q.921 Appendix IV */ \
|
||||
3, /* NM20 - Q.921 Appendix IV */ \
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -73,7 +73,7 @@ static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
|
||||
q921_h *h = (q921_h *)buf;
|
||||
q921_dump(pri, h, len, 1, txrx);
|
||||
if (!((h->h.data[0] & Q921_FRAMETYPE_MASK) & 0x3)) {
|
||||
q931_dump(pri, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
|
||||
q931_dump(pri, h->h.tei, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
|
||||
}
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
165
prisched.c
165
prisched.c
@@ -33,25 +33,43 @@
|
||||
#include "pri_internal.h"
|
||||
|
||||
|
||||
/*! \brief The maximum number of timers that were active at once. */
|
||||
static int maxsched = 0;
|
||||
|
||||
/* Scheduler routines */
|
||||
int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data)
|
||||
|
||||
/*!
|
||||
* \brief Start a timer to schedule an event.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param ms Number of milliseconds to scheduled event.
|
||||
* \param function Callback function to call when timeout.
|
||||
* \param data Value to give callback function when timeout.
|
||||
*
|
||||
* \retval 0 if scheduler table is full and could not schedule the event.
|
||||
* \retval id Scheduled event id.
|
||||
*/
|
||||
int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data)
|
||||
{
|
||||
int x;
|
||||
struct timeval tv;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
while (pri->master)
|
||||
pri = pri->master;
|
||||
for (x=1;x<MAX_SCHED;x++)
|
||||
if (!pri->pri_sched[x].callback)
|
||||
break;
|
||||
if (x == MAX_SCHED) {
|
||||
pri_error(pri, "No more room in scheduler\n");
|
||||
return -1;
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
for (x = 0; x < MAX_SCHED; ++x) {
|
||||
if (!ctrl->pri_sched[x].callback) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x == MAX_SCHED) {
|
||||
pri_error(ctrl, "No more room in scheduler\n");
|
||||
return 0;
|
||||
}
|
||||
if (x >= maxsched) {
|
||||
maxsched = x + 1;
|
||||
}
|
||||
if (x > maxsched)
|
||||
maxsched = x;
|
||||
gettimeofday(&tv, NULL);
|
||||
tv.tv_sec += ms / 1000;
|
||||
tv.tv_usec += (ms % 1000) * 1000;
|
||||
@@ -59,71 +77,110 @@ int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), vo
|
||||
tv.tv_usec -= 1000000;
|
||||
tv.tv_sec += 1;
|
||||
}
|
||||
pri->pri_sched[x].when = tv;
|
||||
pri->pri_sched[x].callback = function;
|
||||
pri->pri_sched[x].data = data;
|
||||
return x;
|
||||
ctrl->pri_sched[x].when = tv;
|
||||
ctrl->pri_sched[x].callback = function;
|
||||
ctrl->pri_sched[x].data = data;
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
struct timeval *pri_schedule_next(struct pri *pri)
|
||||
/*!
|
||||
* \brief Determine the time of the next scheduled event to expire.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Time of the next scheduled event to expire or NULL if no timers active.
|
||||
*/
|
||||
struct timeval *pri_schedule_next(struct pri *ctrl)
|
||||
{
|
||||
struct timeval *closest = NULL;
|
||||
int x;
|
||||
/* Check subchannels */
|
||||
if (pri->subchannel)
|
||||
closest = pri_schedule_next(pri->subchannel);
|
||||
for (x=1;x<MAX_SCHED;x++) {
|
||||
if (pri->pri_sched[x].callback &&
|
||||
(!closest || (closest->tv_sec > pri->pri_sched[x].when.tv_sec) ||
|
||||
((closest->tv_sec == pri->pri_sched[x].when.tv_sec) &&
|
||||
(closest->tv_usec > pri->pri_sched[x].when.tv_usec))))
|
||||
closest = &pri->pri_sched[x].when;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
for (x = 0; x < MAX_SCHED; ++x) {
|
||||
if (ctrl->pri_sched[x].callback && (!closest
|
||||
|| (closest->tv_sec > ctrl->pri_sched[x].when.tv_sec)
|
||||
|| ((closest->tv_sec == ctrl->pri_sched[x].when.tv_sec)
|
||||
&& (closest->tv_usec > ctrl->pri_sched[x].when.tv_usec)))) {
|
||||
closest = &ctrl->pri_sched[x].when;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Run all expired timers or return an event generated by an expired timer.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param tv Current time.
|
||||
*
|
||||
* \return Event for upper layer to process or NULL if all expired timers run.
|
||||
*/
|
||||
static pri_event *__pri_schedule_run(struct pri *ctrl, struct timeval *tv)
|
||||
{
|
||||
int x;
|
||||
void (*callback)(void *);
|
||||
void *data;
|
||||
pri_event *e;
|
||||
if (pri->subchannel) {
|
||||
if ((e = __pri_schedule_run(pri->subchannel, tv))) {
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
for (x=1;x<MAX_SCHED;x++) {
|
||||
if (pri->pri_sched[x].callback &&
|
||||
((pri->pri_sched[x].when.tv_sec < tv->tv_sec) ||
|
||||
((pri->pri_sched[x].when.tv_sec == tv->tv_sec) &&
|
||||
(pri->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
|
||||
pri->schedev = 0;
|
||||
callback = pri->pri_sched[x].callback;
|
||||
data = pri->pri_sched[x].data;
|
||||
pri->pri_sched[x].callback = NULL;
|
||||
pri->pri_sched[x].data = NULL;
|
||||
callback(data);
|
||||
if (pri->schedev)
|
||||
return &pri->ev;
|
||||
}
|
||||
for (x = 0; x < MAX_SCHED; ++x) {
|
||||
if (ctrl->pri_sched[x].callback && ((ctrl->pri_sched[x].when.tv_sec < tv->tv_sec)
|
||||
|| ((ctrl->pri_sched[x].when.tv_sec == tv->tv_sec)
|
||||
&& (ctrl->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
|
||||
/* This timer has expired. */
|
||||
ctrl->schedev = 0;
|
||||
callback = ctrl->pri_sched[x].callback;
|
||||
data = ctrl->pri_sched[x].data;
|
||||
ctrl->pri_sched[x].callback = NULL;
|
||||
callback(data);
|
||||
if (ctrl->schedev) {
|
||||
return &ctrl->ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pri_event *pri_schedule_run(struct pri *pri)
|
||||
/*!
|
||||
* \brief Run all expired timers or return an event generated by an expired timer.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Event for upper layer to process or NULL if all expired timers run.
|
||||
*/
|
||||
pri_event *pri_schedule_run(struct pri *ctrl)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
return __pri_schedule_run(pri, &tv);
|
||||
return __pri_schedule_run(ctrl, &tv);
|
||||
}
|
||||
|
||||
|
||||
void pri_schedule_del(struct pri *pri,int id)
|
||||
/*!
|
||||
* \brief Delete a scheduled event.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param id Scheduled event id to delete.
|
||||
* 0 is a disabled/unscheduled event id that is ignored.
|
||||
* 1 - MAX_SCHED is a valid event id.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_schedule_del(struct pri *ctrl, int id)
|
||||
{
|
||||
while (pri->master)
|
||||
pri = pri->master;
|
||||
if ((id >= MAX_SCHED) || (id < 0))
|
||||
pri_error(pri, "Asked to delete sched id %d???\n", id);
|
||||
pri->pri_sched[id].callback = NULL;
|
||||
/* Scheduling runs on master channels only */
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
if (0 < id && id <= MAX_SCHED) {
|
||||
ctrl->pri_sched[id - 1].callback = NULL;
|
||||
} else if (id) {
|
||||
pri_error(ctrl, "Asked to delete sched id %d???\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
983
rose_address.c
Normal file
983
rose_address.c
Normal file
@@ -0,0 +1,983 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief ROSE Addressing-Data-Elements
|
||||
*
|
||||
* Addressing-Data-Elements ETS 300 196-1 D.3
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the public or private network PartyNumber type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
||||
* tags it otherwise.
|
||||
* \param number
|
||||
* \param length_of_number
|
||||
* \param type_of_number
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *rose_enc_NetworkPartyNumber(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const unsigned char *number,
|
||||
size_t length_of_number, u_int8_t type_of_number)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, type_of_number));
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_TYPE_NUMERIC_STRING, number,
|
||||
length_of_number));
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the PartyNumber type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party_number
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_PartyNumber(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePartyNumber *party_number)
|
||||
{
|
||||
switch (party_number->plan) {
|
||||
case 0: /* Unknown PartyNumber */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
||||
party_number->str, party_number->length));
|
||||
break;
|
||||
case 1: /* Public PartyNumber */
|
||||
ASN1_CALL(pos, rose_enc_NetworkPartyNumber(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 1, party_number->str, party_number->length,
|
||||
party_number->ton));
|
||||
break;
|
||||
case 2: /* NSAP encoded PartyNumber */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
|
||||
party_number->str, party_number->length));
|
||||
break;
|
||||
case 3: /* Data PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
|
||||
party_number->str, party_number->length));
|
||||
break;
|
||||
case 4: /* Telex PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4,
|
||||
party_number->str, party_number->length));
|
||||
break;
|
||||
case 5: /* Private PartyNumber */
|
||||
ASN1_CALL(pos, rose_enc_NetworkPartyNumber(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 5, party_number->str, party_number->length,
|
||||
party_number->ton));
|
||||
break;
|
||||
case 8: /* National Standard PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 8,
|
||||
party_number->str, party_number->length));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown numbering plan");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the PartySubaddress type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party_subaddress
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_PartySubaddress(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePartySubaddress *party_subaddress)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
switch (party_subaddress->type) {
|
||||
case 0: /* UserSpecified */
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_TYPE_OCTET_STRING,
|
||||
party_subaddress->u.user_specified.information, party_subaddress->length));
|
||||
if (party_subaddress->u.user_specified.odd_count_present) {
|
||||
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_TYPE_BOOLEAN,
|
||||
party_subaddress->u.user_specified.odd_count));
|
||||
}
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
break;
|
||||
case 1: /* NSAP */
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_TYPE_OCTET_STRING,
|
||||
party_subaddress->u.nsap, party_subaddress->length));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown subaddress type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Address type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
||||
* tags it otherwise.
|
||||
* \param address
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_Address(struct pri *ctrl, unsigned char *pos, unsigned char *end,
|
||||
unsigned tag, const struct roseAddress *address)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &address->number));
|
||||
if (address->subaddress.length) {
|
||||
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end, &address->subaddress));
|
||||
}
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the PresentedNumberUnscreened type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_PresentedNumberUnscreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedNumberUnscreened *party)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
switch (party->presentation) {
|
||||
case 0: /* presentationAllowedNumber */
|
||||
/* EXPLICIT tag */
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &party->number));
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
break;
|
||||
case 1: /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2));
|
||||
break;
|
||||
case 3: /* presentationRestrictedNumber */
|
||||
/* EXPLICIT tag */
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &party->number));
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown presentation type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the NumberScreened type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
||||
* tags it otherwise.
|
||||
* \param screened
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_NumberScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const struct roseNumberScreened *screened)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &screened->number));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
screened->screening_indicator));
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the PresentedNumberScreened type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_PresentedNumberScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedNumberScreened *party)
|
||||
{
|
||||
switch (party->presentation) {
|
||||
case 0: /* presentationAllowedNumber */
|
||||
ASN1_CALL(pos, rose_enc_NumberScreened(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 0, &party->screened));
|
||||
break;
|
||||
case 1: /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2));
|
||||
break;
|
||||
case 3: /* presentationRestrictedNumber */
|
||||
ASN1_CALL(pos, rose_enc_NumberScreened(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 3, &party->screened));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown presentation type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the AddressScreened type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
||||
* tags it otherwise.
|
||||
* \param screened
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_AddressScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const struct roseAddressScreened *screened)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &screened->number));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
screened->screening_indicator));
|
||||
if (screened->subaddress.length) {
|
||||
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end, &screened->subaddress));
|
||||
}
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the PresentedAddressScreened type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_PresentedAddressScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedAddressScreened *party)
|
||||
{
|
||||
switch (party->presentation) {
|
||||
case 0: /* presentationAllowedAddress */
|
||||
ASN1_CALL(pos, rose_enc_AddressScreened(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 0, &party->screened));
|
||||
break;
|
||||
case 1: /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2));
|
||||
break;
|
||||
case 3: /* presentationRestrictedAddress */
|
||||
ASN1_CALL(pos, rose_enc_AddressScreened(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 3, &party->screened));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown presentation type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the NumberDigits PartyNumber argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_number Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_NumberDigits(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartyNumber *party_number)
|
||||
{
|
||||
size_t str_len;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, name, tag, pos, end,
|
||||
sizeof(party_number->str), party_number->str, &str_len));
|
||||
party_number->length = str_len;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the NSAP PartyNumber argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_number Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_NSAPPartyNumber(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartyNumber *party_number)
|
||||
{
|
||||
size_t str_len;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_string_bin(ctrl, name, tag, pos, end,
|
||||
sizeof(party_number->str), party_number->str, &str_len));
|
||||
party_number->length = str_len;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the public or private network PartyNumber argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_number Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_NetworkPartyNumber(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartyNumber *party_number)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "typeOfNumber", tag, pos, seq_end, &value));
|
||||
party_number->ton = value;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_TYPE_NUMERIC_STRING);
|
||||
ASN1_CALL(pos, rose_dec_NumberDigits(ctrl, "numberDigits", tag, pos, seq_end,
|
||||
party_number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the PartyNumber argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_number Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_PartyNumber(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartyNumber *party_number)
|
||||
{
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s PartyNumber\n", name);
|
||||
}
|
||||
party_number->ton = 0; /* unknown */
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
party_number->plan = 0; /* Unknown PartyNumber */
|
||||
ASN1_CALL(pos, rose_dec_NumberDigits(ctrl, "unknownPartyNumber", tag, pos, end,
|
||||
party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
party_number->plan = 1; /* Public PartyNumber */
|
||||
ASN1_CALL(pos, rose_dec_NetworkPartyNumber(ctrl, "publicPartyNumber", tag, pos,
|
||||
end, party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
party_number->plan = 2; /* NSAP encoded PartyNumber */
|
||||
ASN1_CALL(pos, rose_dec_NSAPPartyNumber(ctrl, "nsapEncodedPartyNumber", tag, pos,
|
||||
end, party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
party_number->plan = 3; /* Data PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, rose_dec_NumberDigits(ctrl, "dataPartyNumber", tag, pos, end,
|
||||
party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
party_number->plan = 4; /* Telex PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, rose_dec_NumberDigits(ctrl, "telexPartyNumber", tag, pos, end,
|
||||
party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
party_number->plan = 5; /* Private PartyNumber */
|
||||
ASN1_CALL(pos, rose_dec_NetworkPartyNumber(ctrl, "privatePartyNumber", tag, pos,
|
||||
end, party_number));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 8:
|
||||
party_number->plan = 8; /* National Standard PartyNumber (Not used) */
|
||||
ASN1_CALL(pos, rose_dec_NumberDigits(ctrl, "nationalStandardPartyNumber", tag,
|
||||
pos, end, party_number));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the User PartySubaddress argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_subaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_UserSubaddress(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartySubaddress *party_subaddress)
|
||||
{
|
||||
size_t str_len;
|
||||
int32_t odd_count;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
party_subaddress->type = 0; /* UserSpecified */
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s UserSpecified %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
/* SubaddressInformation */
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_TYPE_OCTET_STRING);
|
||||
ASN1_CALL(pos, asn1_dec_string_bin(ctrl, "subaddressInformation", tag, pos, seq_end,
|
||||
sizeof(party_subaddress->u.user_specified.information),
|
||||
party_subaddress->u.user_specified.information, &str_len));
|
||||
party_subaddress->length = str_len;
|
||||
|
||||
if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
/*
|
||||
* The optional odd count indicator must be present since there
|
||||
* is something left.
|
||||
*/
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_BOOLEAN);
|
||||
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "oddCount", tag, pos, seq_end,
|
||||
&odd_count));
|
||||
party_subaddress->u.user_specified.odd_count = odd_count;
|
||||
party_subaddress->u.user_specified.odd_count_present = 1;
|
||||
} else {
|
||||
party_subaddress->u.user_specified.odd_count = 0;
|
||||
party_subaddress->u.user_specified.odd_count_present = 0;
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the NSAP PartySubaddress argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_subaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_NSAPSubaddress(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartySubaddress *party_subaddress)
|
||||
{
|
||||
size_t str_len;
|
||||
|
||||
party_subaddress->type = 1; /* NSAP */
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_string_bin(ctrl, name, tag, pos, end,
|
||||
sizeof(party_subaddress->u.nsap), party_subaddress->u.nsap, &str_len));
|
||||
party_subaddress->length = str_len;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the PartySubaddress argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party_subaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_PartySubaddress(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartySubaddress *party_subaddress)
|
||||
{
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s PartySubaddress\n", name);
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_TAG_SEQUENCE:
|
||||
ASN1_CALL(pos, rose_dec_UserSubaddress(ctrl, "user", tag, pos, end,
|
||||
party_subaddress));
|
||||
break;
|
||||
case ASN1_TYPE_OCTET_STRING:
|
||||
case ASN1_TYPE_OCTET_STRING | ASN1_PC_CONSTRUCTED:
|
||||
ASN1_CALL(pos, rose_dec_NSAPSubaddress(ctrl, "nsap", tag, pos, end,
|
||||
party_subaddress));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Address argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param address Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_Address(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, struct roseAddress *address)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s Address %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "partyNumber", tag, pos, seq_end,
|
||||
&address->number));
|
||||
|
||||
if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
/* The optional subaddress must be present since there is something left. */
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "partySubaddress", tag, pos,
|
||||
seq_end, &address->subaddress));
|
||||
} else {
|
||||
address->subaddress.length = 0; /* Subaddress not present */
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the PresentedNumberUnscreened argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_PresentedNumberUnscreened(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedNumberUnscreened *party)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s PresentedNumberUnscreened\n", name);
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
party->presentation = 0; /* presentationAllowedNumber */
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "presentationAllowedNumber", tag, pos,
|
||||
seq_end, &party->number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
party->presentation = 1; /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "presentationRestricted", tag, pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
party->presentation = 2; /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "numberNotAvailableDueToInterworking", tag,
|
||||
pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
party->presentation = 3; /* presentationRestrictedNumber */
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "presentationRestrictedNumber", tag,
|
||||
pos, seq_end, &party->number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the NumberScreened argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param screened Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_NumberScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseNumberScreened *screened)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s NumberScreened %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "partyNumber", tag, pos, seq_end,
|
||||
&screened->number));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "screeningIndicator", tag, pos, seq_end, &value));
|
||||
screened->screening_indicator = value;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the PresentedNumberScreened argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_PresentedNumberScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedNumberScreened *party)
|
||||
{
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s PresentedNumberScreened\n", name);
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
|
||||
party->presentation = 0; /* presentationAllowedNumber */
|
||||
ASN1_CALL(pos, rose_dec_NumberScreened(ctrl, "presentationAllowedNumber", tag,
|
||||
pos, end, &party->screened));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
party->presentation = 1; /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "presentationRestricted", tag, pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
party->presentation = 2; /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "numberNotAvailableDueToInterworking", tag,
|
||||
pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
|
||||
party->presentation = 3; /* presentationRestrictedNumber */
|
||||
ASN1_CALL(pos, rose_dec_NumberScreened(ctrl, "presentationRestrictedNumber", tag,
|
||||
pos, end, &party->screened));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the AddressScreened argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param screened Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_AddressScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseAddressScreened *screened)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s AddressScreened %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "partyNumber", tag, pos, seq_end,
|
||||
&screened->number));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "screeningIndicator", tag, pos, seq_end, &value));
|
||||
screened->screening_indicator = value;
|
||||
|
||||
if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
/* The optional subaddress must be present since there is something left. */
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "partySubaddress", tag, pos,
|
||||
seq_end, &screened->subaddress));
|
||||
} else {
|
||||
screened->subaddress.length = 0; /* Subaddress not present */
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the PresentedAddressScreened argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_PresentedAddressScreened(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedAddressScreened *party)
|
||||
{
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s PresentedAddressScreened\n", name);
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
|
||||
party->presentation = 0; /* presentationAllowedAddress */
|
||||
ASN1_CALL(pos, rose_dec_AddressScreened(ctrl, "presentationAllowedAddress", tag,
|
||||
pos, end, &party->screened));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
party->presentation = 1; /* presentationRestricted */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "presentationRestricted", tag, pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
party->presentation = 2; /* numberNotAvailableDueToInterworking */
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "numberNotAvailableDueToInterworking", tag,
|
||||
pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
|
||||
party->presentation = 3; /* presentationRestrictedAddress */
|
||||
ASN1_CALL(pos, rose_dec_AddressScreened(ctrl, "presentationRestrictedAddress",
|
||||
tag, pos, end, &party->screened));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_address.c */
|
||||
1929
rose_etsi_aoc.c
Normal file
1929
rose_etsi_aoc.c
Normal file
File diff suppressed because it is too large
Load Diff
1623
rose_etsi_diversion.c
Normal file
1623
rose_etsi_diversion.c
Normal file
File diff suppressed because it is too large
Load Diff
332
rose_etsi_ect.c
Normal file
332
rose_etsi_ect.c
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief ROSE Explicit Call Transfer operations.
|
||||
*
|
||||
* Explicit Call Transfer (ECT) Supplementary Services ETS 300 369-1
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Encode the ExplicitEctExecute invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
|
||||
args->etsi.ExplicitEctExecute.link_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the SubaddressTransfer invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_enc_PartySubaddress(ctrl, pos, end,
|
||||
&args->etsi.SubaddressTransfer.subaddress);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the EctLinkIdRequest result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
|
||||
args->etsi.EctLinkIdRequest.link_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the EctInform invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_EctInform_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseEtsiEctInform_ARG *ect_inform;
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ect_inform = &args->etsi.EctInform;
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, ect_inform->status));
|
||||
if (ect_inform->redirection_present) {
|
||||
ASN1_CALL(pos, rose_enc_PresentedNumberUnscreened(ctrl, pos, end,
|
||||
&ect_inform->redirection));
|
||||
}
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the EctLoopTest invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
|
||||
args->etsi.EctLoopTest.call_transfer_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the EctLoopTest result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
args->etsi.EctLoopTest.loop_result);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the ExplicitEctExecute invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
|
||||
args->etsi.ExplicitEctExecute.link_id = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the SubaddressTransfer invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_dec_PartySubaddress(ctrl, "transferredToSubaddress", tag, pos, end,
|
||||
&args->etsi.SubaddressTransfer.subaddress);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the EctLinkIdRequest result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
|
||||
args->etsi.EctLinkIdRequest.link_id = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the EctInform invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_EctInform_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
struct roseEtsiEctInform_ARG *ect_inform;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
int32_t value;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " EctInform %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ect_inform = &args->etsi.EctInform;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callStatus", tag, pos, seq_end, &value));
|
||||
ect_inform->status = value;
|
||||
|
||||
if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PresentedNumberUnscreened(ctrl, "redirectionNumber", tag,
|
||||
pos, seq_end, &ect_inform->redirection));
|
||||
ect_inform->redirection_present = 1;
|
||||
} else {
|
||||
ect_inform->redirection_present = 0;
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the EctLoopTest invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callTransferId", tag, pos, end, &value));
|
||||
args->etsi.EctLoopTest.call_transfer_id = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the EctLoopTest result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "loopResult", tag, pos, end, &value));
|
||||
args->etsi.EctLoopTest.loop_result = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_etsi_ect.c */
|
||||
477
rose_internal.h
Normal file
477
rose_internal.h
Normal file
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief Internal definitions and prototypes for ROSE.
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
#ifndef _LIBPRI_ROSE_INTERNAL_H
|
||||
#define _LIBPRI_ROSE_INTERNAL_H
|
||||
|
||||
#include "rose.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Embedded-Q931-Types */
|
||||
unsigned char *rose_enc_Q931ie(struct pri *ctrl, unsigned char *pos, unsigned char *end,
|
||||
unsigned tag, const struct roseQ931ie *q931ie);
|
||||
|
||||
const unsigned char *rose_dec_Q931ie(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, struct roseQ931ie *q931ie,
|
||||
size_t contents_size);
|
||||
|
||||
/* Addressing-Data-Elements */
|
||||
unsigned char *rose_enc_PartyNumber(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePartyNumber *party_number);
|
||||
unsigned char *rose_enc_PartySubaddress(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePartySubaddress *party_subaddress);
|
||||
unsigned char *rose_enc_Address(struct pri *ctrl, unsigned char *pos, unsigned char *end,
|
||||
unsigned tag, const struct roseAddress *address);
|
||||
unsigned char *rose_enc_PresentedNumberUnscreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedNumberUnscreened *party);
|
||||
unsigned char *rose_enc_NumberScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const struct roseNumberScreened *screened);
|
||||
unsigned char *rose_enc_PresentedNumberScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedNumberScreened *party);
|
||||
unsigned char *rose_enc_AddressScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const struct roseAddressScreened *screened);
|
||||
unsigned char *rose_enc_PresentedAddressScreened(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct rosePresentedAddressScreened *party);
|
||||
|
||||
const unsigned char *rose_dec_PartyNumber(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartyNumber *party_number);
|
||||
const unsigned char *rose_dec_PartySubaddress(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePartySubaddress *party_subaddress);
|
||||
const unsigned char *rose_dec_Address(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, struct roseAddress *address);
|
||||
const unsigned char *rose_dec_PresentedNumberUnscreened(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedNumberUnscreened *party);
|
||||
const unsigned char *rose_dec_NumberScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseNumberScreened *screened);
|
||||
const unsigned char *rose_dec_PresentedNumberScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedNumberScreened *party);
|
||||
const unsigned char *rose_dec_AddressScreened(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseAddressScreened *screened);
|
||||
const unsigned char *rose_dec_PresentedAddressScreened(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct rosePresentedAddressScreened *party);
|
||||
|
||||
/* ETSI Advice-of-Charge (AOC) */
|
||||
unsigned char *rose_enc_etsi_ChargingRequest_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_ChargingRequest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCSCurrency_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCSSpecialArr_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCDCurrency_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCDChargingUnit_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCECurrency_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_AOCEChargingUnit_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_etsi_ChargingRequest_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_ChargingRequest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCSCurrency_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCSSpecialArr_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCDCurrency_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCDChargingUnit_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCECurrency_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_AOCEChargingUnit_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* ETSI Call Diversion */
|
||||
unsigned char *rose_enc_etsi_ActivationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_DeactivationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_ActivationStatusNotificationDiv_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_DeactivationStatusNotificationDiv_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_InterrogationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_InterrogationDiversion_RES(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_etsi_DiversionInformation_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_CallDeflection_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_CallRerouting_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_InterrogateServedUserNumbers_RES(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_etsi_DivertingLegInformation1_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_DivertingLegInformation2_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_DivertingLegInformation3_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_etsi_ActivationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_DeactivationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_ActivationStatusNotificationDiv_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_DeactivationStatusNotificationDiv_ARG(struct pri
|
||||
*ctrl, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_InterrogationDiversion_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_InterrogationDiversion_RES(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_etsi_DiversionInformation_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_CallDeflection_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_CallRerouting_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_InterrogateServedUserNumbers_RES(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_etsi_DivertingLegInformation1_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_DivertingLegInformation2_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_DivertingLegInformation3_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* ETSI Explicit Call Transfer (ECT) */
|
||||
unsigned char *rose_enc_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_etsi_EctInform_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
|
||||
const unsigned char *rose_dec_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_etsi_EctInform_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
|
||||
/* Q.SIG Name-Operations */
|
||||
unsigned char *rose_enc_qsig_Name(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct roseQsigName *name);
|
||||
|
||||
const unsigned char *rose_dec_qsig_Name(struct pri *ctrl, const char *fname,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigName *name);
|
||||
|
||||
unsigned char *rose_enc_qsig_CallingName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CalledName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_BusyName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_CallingName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CalledName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_BusyName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/*
|
||||
* Q.SIG Dummy invoke/result argument used by:
|
||||
* SS-AOC-Operations,
|
||||
* Call-Transfer-Operations,
|
||||
* Call-Diversion-Operations,
|
||||
* and SS-MWI-Operations.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_DummyArg_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_DummyRes_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_DummyArg_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_DummyRes_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
|
||||
/* Q.SIG SS-AOC-Operations */
|
||||
unsigned char *rose_enc_qsig_ChargeRequest_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_ChargeRequest_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_qsig_AocFinal_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_AocInterim_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_AocRate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_AocComplete_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_AocComplete_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_qsig_AocDivChargeReq_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_ChargeRequest_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_ChargeRequest_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocFinal_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocInterim_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocRate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocComplete_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocComplete_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_qsig_AocDivChargeReq_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* Q.SIG Call-Diversion-Operations */
|
||||
unsigned char *rose_enc_qsig_ActivateDiversionQ_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_DeactivateDiversionQ_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_InterrogateDiversionQ_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_InterrogateDiversionQ_RES(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_qsig_CheckRestriction_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CallRerouting_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_DivertingLegInformation1_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_DivertingLegInformation2_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_DivertingLegInformation3_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_ActivateDiversionQ_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_DeactivateDiversionQ_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_InterrogateDiversionQ_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_InterrogateDiversionQ_RES(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_qsig_CheckRestriction_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallRerouting_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_DivertingLegInformation1_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_DivertingLegInformation2_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_DivertingLegInformation3_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* Q.SIG Call-Transfer-Operations (CT) */
|
||||
unsigned char *rose_enc_qsig_CallTransferIdentify_RES(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CallTransferComplete_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_CallTransferIdentify_RES(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallTransferComplete_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* Q.SIG SS-MWI-Operations */
|
||||
unsigned char *rose_enc_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_MWIDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_MWIInterrogate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_qsig_MWIInterrogate_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
|
||||
const unsigned char *rose_dec_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_MWIDeactivate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_MWIInterrogate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_qsig_MWIInterrogate_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
|
||||
/* Northern Telecom DMS-100 operations */
|
||||
unsigned char *rose_enc_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args);
|
||||
unsigned char *rose_enc_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args);
|
||||
const unsigned char *rose_dec_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
/* National ISDN 2 (NI2) operations */
|
||||
unsigned char *rose_enc_ni2_InformationFollowing_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
unsigned char *rose_enc_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args);
|
||||
|
||||
const unsigned char *rose_dec_ni2_InformationFollowing_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
const unsigned char *rose_dec_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBPRI_ROSE_INTERNAL_H */
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_internal.h */
|
||||
277
rose_other.c
Normal file
277
rose_other.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief Switch type operations for: NI2, 4ESS, 5ESS, DMS-100
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Encode the DMS-100 RLT_OperationInd result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
return asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
||||
args->dms100.RLT_OperationInd.call_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the DMS-100 RLT_ThirdParty invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseDms100RLTThirdParty_ARG *rlt_thirdparty;
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
rlt_thirdparty = &args->dms100.RLT_ThirdParty;
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
||||
rlt_thirdparty->call_id));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
|
||||
rlt_thirdparty->reason));
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the DMS-100 RLT_OperationInd result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callId", tag, pos, end, &value));
|
||||
args->dms100.RLT_OperationInd.call_id = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the DMS-100 RLT_ThirdParty invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseDms100RLTThirdParty_ARG *rlt_third_party;
|
||||
|
||||
rlt_third_party = &args->dms100.RLT_ThirdParty;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " RLT_ThirdParty %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callId", tag, pos, seq_end, &value));
|
||||
rlt_third_party->call_id = value;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "reason", tag, pos, seq_end, &value));
|
||||
rlt_third_party->reason = value;
|
||||
|
||||
/* Fixup will skip over any OPTIONAL information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the NI2 InformationFollowing invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_ni2_InformationFollowing_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
/* Encode the unknown enumeration value. */
|
||||
return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
args->ni2.InformationFollowing.value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the NI2 InitiateTransfer invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseNi2InitiateTransfer_ARG *initiate_transfer;
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
initiate_transfer = &args->ni2.InitiateTransfer;
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
|
||||
initiate_transfer->call_reference));
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the NI2 InformationFollowing invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_ni2_InformationFollowing_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "unknown", tag, pos, end, &value));
|
||||
args->ni2.InformationFollowing.value = value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the NI2 InitiateTransfer invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseNi2InitiateTransfer_ARG *initiate_transfer;
|
||||
|
||||
initiate_transfer = &args->ni2.InitiateTransfer;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " InitiateTransfer %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callReference", tag, pos, seq_end, &value));
|
||||
initiate_transfer->call_reference = value;
|
||||
|
||||
/* Fixup will skip over any OPTIONAL information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_other.c */
|
||||
100
rose_q931.c
Normal file
100
rose_q931.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief ROSE Q.931 ie encode/decode functions
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.931 ie value.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_CLASS_APPLICATION | 0 unless the caller
|
||||
* implicitly tags it otherwise.
|
||||
* \param q931ie Q931 ie information to encode.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_Q931ie(struct pri *ctrl, unsigned char *pos, unsigned char *end,
|
||||
unsigned tag, const struct roseQ931ie *q931ie)
|
||||
{
|
||||
return asn1_enc_string_bin(pos, end, tag, q931ie->contents, q931ie->length);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.931 ie value.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param q931ie Parameter storage to fill.
|
||||
* \param contents_size Amount of space "allocated" for the q931ie->contents
|
||||
* element. Must have enough room for a null terminator.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_Q931ie(struct pri *ctrl, const char *name, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, struct roseQ931ie *q931ie,
|
||||
size_t contents_size)
|
||||
{
|
||||
size_t str_len;
|
||||
|
||||
/* NOTE: The q931ie->contents memory is "allocated" after the struct. */
|
||||
ASN1_CALL(pos, asn1_dec_string_bin(ctrl, name, tag, pos, end, contents_size,
|
||||
q931ie->contents, &str_len));
|
||||
q931ie->length = str_len;
|
||||
|
||||
/*
|
||||
* NOTE: We may want to do some basic decoding of the Q.931 ie list
|
||||
* for debug purposes.
|
||||
*/
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_q931.c */
|
||||
1714
rose_qsig_aoc.c
Normal file
1714
rose_qsig_aoc.c
Normal file
File diff suppressed because it is too large
Load Diff
883
rose_qsig_ct.c
Normal file
883
rose_qsig_ct.c
Normal file
@@ -0,0 +1,883 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief Q.SIG ROSE Call-Transfer-Operations (CT)
|
||||
*
|
||||
* Call-Transfer-Operations ECMA-178 Annex F Table F.1
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferIdentify result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferIdentify_RES(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTIdentifyRes_RES *call_transfer_identify;
|
||||
|
||||
call_transfer_identify = &args->qsig.CallTransferIdentify;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
|
||||
call_transfer_identify->call_id, sizeof(call_transfer_identify->call_id) - 1));
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&call_transfer_identify->rerouting_number));
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferInitiate invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTInitiateArg_ARG *call_transfer_initiate;
|
||||
|
||||
call_transfer_initiate = &args->qsig.CallTransferInitiate;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
|
||||
call_transfer_initiate->call_id, sizeof(call_transfer_initiate->call_id) - 1));
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&call_transfer_initiate->rerouting_number));
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferSetup invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTSetupArg_ARG *call_transfer_setup;
|
||||
|
||||
call_transfer_setup = &args->qsig.CallTransferSetup;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
|
||||
call_transfer_setup->call_id, sizeof(call_transfer_setup->call_id) - 1));
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferActive invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTActiveArg_ARG *call_transfer_active;
|
||||
|
||||
call_transfer_active = &args->qsig.CallTransferActive;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PresentedAddressScreened(ctrl, pos, end,
|
||||
&call_transfer_active->connected));
|
||||
|
||||
if (call_transfer_active->q931ie.length) {
|
||||
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
|
||||
&call_transfer_active->q931ie));
|
||||
}
|
||||
|
||||
if (call_transfer_active->connected_name_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
|
||||
&call_transfer_active->connected_name));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferComplete invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferComplete_ARG(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTCompleteArg_ARG *call_transfer_complete;
|
||||
|
||||
call_transfer_complete = &args->qsig.CallTransferComplete;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
call_transfer_complete->end_designation));
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PresentedNumberScreened(ctrl, pos, end,
|
||||
&call_transfer_complete->redirection));
|
||||
|
||||
if (call_transfer_complete->q931ie.length) {
|
||||
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
|
||||
&call_transfer_complete->q931ie));
|
||||
}
|
||||
|
||||
if (call_transfer_complete->redirection_name_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
|
||||
&call_transfer_complete->redirection_name));
|
||||
}
|
||||
|
||||
if (call_transfer_complete->call_status) {
|
||||
/* Not the DEFAULT value */
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
call_transfer_complete->call_status));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallTransferUpdate invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigCTUpdateArg_ARG *call_transfer_update;
|
||||
|
||||
call_transfer_update = &args->qsig.CallTransferUpdate;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PresentedNumberScreened(ctrl, pos, end,
|
||||
&call_transfer_update->redirection));
|
||||
|
||||
if (call_transfer_update->redirection_name_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
|
||||
&call_transfer_update->redirection_name));
|
||||
}
|
||||
|
||||
if (call_transfer_update->q931ie.length) {
|
||||
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
|
||||
&call_transfer_update->q931ie));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG SubaddressTransfer invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigSubaddressTransferArg_ARG *subaddress_transfer;
|
||||
|
||||
subaddress_transfer = &args->qsig.SubaddressTransfer;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
|
||||
&subaddress_transfer->redirection_subaddress));
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG DummyArg invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*
|
||||
* \details
|
||||
* DummyArg ::= CHOICE {
|
||||
* none NULL,
|
||||
* extension [1] IMPLICIT Extension,
|
||||
* multipleExtension [2] IMPLICIT SEQUENCE OF Extension
|
||||
* }
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_DummyArg_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG DummyRes result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*
|
||||
* \details
|
||||
* DummyRes ::= CHOICE {
|
||||
* none NULL,
|
||||
* extension [1] IMPLICIT Extension,
|
||||
* multipleExtension [2] IMPLICIT SEQUENCE OF Extension
|
||||
* }
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_DummyRes_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferIdentify result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferIdentify_RES(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_result_args *args)
|
||||
{
|
||||
size_t str_len;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseQsigCTIdentifyRes_RES *call_transfer_identify;
|
||||
|
||||
call_transfer_identify = &args->qsig.CallTransferIdentify;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferIdentify %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
|
||||
sizeof(call_transfer_identify->call_id), call_transfer_identify->call_id,
|
||||
&str_len));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "reroutingNumber", tag, pos, seq_end,
|
||||
&call_transfer_identify->rerouting_number));
|
||||
|
||||
/* Fixup will skip over any OPTIONAL manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferInitiate invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args)
|
||||
{
|
||||
size_t str_len;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseQsigCTInitiateArg_ARG *call_transfer_initiate;
|
||||
|
||||
call_transfer_initiate = &args->qsig.CallTransferInitiate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferInitiate %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
|
||||
sizeof(call_transfer_initiate->call_id), call_transfer_initiate->call_id,
|
||||
&str_len));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "reroutingNumber", tag, pos, seq_end,
|
||||
&call_transfer_initiate->rerouting_number));
|
||||
|
||||
/* Fixup will skip over any OPTIONAL manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferSetup invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
size_t str_len;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseQsigCTSetupArg_ARG *call_transfer_setup;
|
||||
|
||||
call_transfer_setup = &args->qsig.CallTransferSetup;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferSetup %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
|
||||
sizeof(call_transfer_setup->call_id), call_transfer_setup->call_id, &str_len));
|
||||
|
||||
/* Fixup will skip over any OPTIONAL manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferActive invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigCTActiveArg_ARG *call_transfer_active;
|
||||
|
||||
call_transfer_active = &args->qsig.CallTransferActive;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferActive %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PresentedAddressScreened(ctrl, "connectedAddress", tag, pos,
|
||||
seq_end, &call_transfer_active->connected));
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
call_transfer_active->q931ie.length = 0;
|
||||
call_transfer_active->connected_name_present = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_APPLICATION | 0:
|
||||
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
|
||||
seq_end, &call_transfer_active->q931ie,
|
||||
sizeof(call_transfer_active->q931ie_contents)));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "connectedName", tag, pos, seq_end,
|
||||
&call_transfer_active->connected_name));
|
||||
call_transfer_active->connected_name_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExtension %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferComplete invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferComplete_ARG(struct pri *ctrl,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigCTCompleteArg_ARG *call_transfer_complete;
|
||||
|
||||
call_transfer_complete = &args->qsig.CallTransferComplete;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferComplete %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "endDesignation", tag, pos, seq_end, &value));
|
||||
call_transfer_complete->end_designation = value;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PresentedNumberScreened(ctrl, "redirectionNumber", tag, pos,
|
||||
seq_end, &call_transfer_complete->redirection));
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
call_transfer_complete->q931ie.length = 0;
|
||||
call_transfer_complete->redirection_name_present = 0;
|
||||
call_transfer_complete->call_status = 0; /* DEFAULT answered */
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_APPLICATION | 0:
|
||||
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
|
||||
seq_end, &call_transfer_complete->q931ie,
|
||||
sizeof(call_transfer_complete->q931ie_contents)));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "redirectionName", tag, pos, seq_end,
|
||||
&call_transfer_complete->redirection_name));
|
||||
call_transfer_complete->redirection_name_present = 1;
|
||||
break;
|
||||
case ASN1_TYPE_ENUMERATED:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "callStatus", tag, pos, seq_end, &value));
|
||||
call_transfer_complete->call_status = value;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExtension %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallTransferUpdate invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigCTUpdateArg_ARG *call_transfer_update;
|
||||
|
||||
call_transfer_update = &args->qsig.CallTransferUpdate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " CallTransferUpdate %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PresentedNumberScreened(ctrl, "redirectionNumber", tag, pos,
|
||||
seq_end, &call_transfer_update->redirection));
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
call_transfer_update->redirection_name_present = 0;
|
||||
call_transfer_update->q931ie.length = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "redirectionName", tag, pos, seq_end,
|
||||
&call_transfer_update->redirection_name));
|
||||
call_transfer_update->redirection_name_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_APPLICATION | 0:
|
||||
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
|
||||
seq_end, &call_transfer_update->q931ie,
|
||||
sizeof(call_transfer_update->q931ie_contents)));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExtension %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG SubaddressTransfer invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseQsigSubaddressTransferArg_ARG *subaddress_transfer;
|
||||
|
||||
subaddress_transfer = &args->qsig.SubaddressTransfer;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " SubaddressTransfer %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "redirectionSubaddress", tag, pos,
|
||||
seq_end, &subaddress_transfer->redirection_subaddress));
|
||||
|
||||
/* Fixup will skip over any OPTIONAL manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG DummyArg invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*
|
||||
* \details
|
||||
* DummyArg ::= CHOICE {
|
||||
* none NULL,
|
||||
* extension [1] IMPLICIT Extension,
|
||||
* multipleExtension [2] IMPLICIT SEQUENCE OF Extension
|
||||
* }
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_DummyArg_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
const char *name;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
switch (tag) {
|
||||
case ASN1_TYPE_NULL:
|
||||
return asn1_dec_null(ctrl, "none", tag, pos, end);
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
|
||||
name = "extension Extension";
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
|
||||
name = "multipleExtension SEQUENCE OF Extension";
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG DummyRes result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*
|
||||
* \details
|
||||
* DummyRes ::= CHOICE {
|
||||
* none NULL,
|
||||
* extension [1] IMPLICIT Extension,
|
||||
* multipleExtension [2] IMPLICIT SEQUENCE OF Extension
|
||||
* }
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_DummyRes_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
||||
{
|
||||
const char *name;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
switch (tag) {
|
||||
case ASN1_TYPE_NULL:
|
||||
return asn1_dec_null(ctrl, "none", tag, pos, end);
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
|
||||
name = "extension Extension";
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
|
||||
name = "multipleExtension SEQUENCE OF Extension";
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_qsig_ct.c */
|
||||
1390
rose_qsig_diversion.c
Normal file
1390
rose_qsig_diversion.c
Normal file
File diff suppressed because it is too large
Load Diff
790
rose_qsig_mwi.c
Normal file
790
rose_qsig_mwi.c
Normal file
@@ -0,0 +1,790 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief Q.SIG ROSE SS-MWI-Operations
|
||||
*
|
||||
* SS-MWI-Operations ECMA-242 Annex E Table E.1
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the MsgCentreId type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param msg_centre_id
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *rose_enc_qsig_MsgCentreId(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct roseQsigMsgCentreId *msg_centre_id)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
switch (msg_centre_id->type) {
|
||||
case 0: /* integer */
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
||||
msg_centre_id->u.integer));
|
||||
break;
|
||||
case 1: /* partyNumber */
|
||||
/* EXPLICIT tag */
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &msg_centre_id->u.number));
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
break;
|
||||
case 2: /* numericString */
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
|
||||
msg_centre_id->u.str, sizeof(msg_centre_id->u.str) - 1));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown MsgCentreId type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the MWIActivate invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseQsigMWIActivateArg *mwi_activate;
|
||||
unsigned char *seq_len;
|
||||
unsigned char *explicit_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
mwi_activate = &args->qsig.MWIActivate;
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&mwi_activate->served_user_number));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
mwi_activate->basic_service));
|
||||
if (mwi_activate->msg_centre_id_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_MsgCentreId(ctrl, pos, end,
|
||||
&mwi_activate->msg_centre_id));
|
||||
}
|
||||
if (mwi_activate->number_of_messages_present) {
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
|
||||
mwi_activate->number_of_messages));
|
||||
}
|
||||
if (mwi_activate->originating_number.length) {
|
||||
/* EXPLICIT tag */
|
||||
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4);
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&mwi_activate->originating_number));
|
||||
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
|
||||
}
|
||||
if (mwi_activate->timestamp_present) {
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
|
||||
mwi_activate->timestamp, sizeof(mwi_activate->timestamp) - 1));
|
||||
}
|
||||
if (mwi_activate->priority_present) {
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5,
|
||||
mwi_activate->priority));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the MWIDeactivate invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_MWIDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseQsigMWIDeactivateArg *mwi_deactivate;
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
mwi_deactivate = &args->qsig.MWIDeactivate;
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&mwi_deactivate->served_user_number));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
mwi_deactivate->basic_service));
|
||||
if (mwi_deactivate->msg_centre_id_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_MsgCentreId(ctrl, pos, end,
|
||||
&mwi_deactivate->msg_centre_id));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the MWIInterrogate invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_MWIInterrogate_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
const struct roseQsigMWIInterrogateArg *mwi_interrogate;
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
mwi_interrogate = &args->qsig.MWIInterrogate;
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&mwi_interrogate->served_user_number));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
|
||||
mwi_interrogate->basic_service));
|
||||
if (mwi_interrogate->msg_centre_id_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_MsgCentreId(ctrl, pos, end,
|
||||
&mwi_interrogate->msg_centre_id));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the MWIInterrogateResElt type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
||||
* tags it otherwise.
|
||||
* \param record
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *rose_enc_qsig_MWIInterrogateResElt(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, unsigned tag,
|
||||
const struct roseQsigMWIInterrogateResElt *record)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
unsigned char *explicit_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, record->basic_service));
|
||||
if (record->msg_centre_id_present) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_MsgCentreId(ctrl, pos, end,
|
||||
&record->msg_centre_id));
|
||||
}
|
||||
if (record->number_of_messages_present) {
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
|
||||
record->number_of_messages));
|
||||
}
|
||||
if (record->originating_number.length) {
|
||||
/* EXPLICIT tag */
|
||||
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4);
|
||||
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
|
||||
&record->originating_number));
|
||||
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
|
||||
}
|
||||
if (record->timestamp_present) {
|
||||
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
|
||||
record->timestamp, sizeof(record->timestamp) - 1));
|
||||
}
|
||||
if (record->priority_present) {
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5,
|
||||
record->priority));
|
||||
}
|
||||
|
||||
/* No extension to encode */
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the MWIInterrogate result facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_MWIInterrogate_RES(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_result_args *args)
|
||||
{
|
||||
unsigned index;
|
||||
unsigned char *seq_len;
|
||||
const struct roseQsigMWIInterrogateRes *mwi_interrogate;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
|
||||
|
||||
mwi_interrogate = &args->qsig.MWIInterrogate;
|
||||
for (index = 0; index < mwi_interrogate->num_records; ++index) {
|
||||
ASN1_CALL(pos, rose_enc_qsig_MWIInterrogateResElt(ctrl, pos, end,
|
||||
ASN1_TAG_SEQUENCE, &mwi_interrogate->list[index]));
|
||||
}
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the MsgCentreId argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param msg_centre_id Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_qsig_MsgCentreId(struct pri *ctrl, const char *name,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigMsgCentreId *msg_centre_id)
|
||||
{
|
||||
int32_t value;
|
||||
size_t str_len;
|
||||
int length;
|
||||
int explicit_offset;
|
||||
const unsigned char *explicit_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s MsgCentreId\n", name);
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
msg_centre_id->type = 0; /* integer */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "integer", tag, pos, end, &value));
|
||||
msg_centre_id->u.integer = value;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
|
||||
msg_centre_id->type = 1; /* partyNumber */
|
||||
|
||||
/* Remove EXPLICIT tag */
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "partyNumber", tag, pos, explicit_end,
|
||||
&msg_centre_id->u.number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, end);
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
|
||||
msg_centre_id->type = 2; /* numericString */
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "numericString", tag, pos, end,
|
||||
sizeof(msg_centre_id->u.str), msg_centre_id->u.str, &str_len));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG MWIActivate invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
size_t str_len;
|
||||
int length;
|
||||
int seq_offset;
|
||||
int explicit_offset;
|
||||
const unsigned char *explicit_end;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigMWIActivateArg *mwi_activate;
|
||||
|
||||
mwi_activate = &args->qsig.MWIActivate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " MWIActivateArg %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "servedUserNr", tag, pos, seq_end,
|
||||
&mwi_activate->served_user_number));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
|
||||
mwi_activate->basic_service = value;
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
mwi_activate->msg_centre_id_present = 0;
|
||||
mwi_activate->number_of_messages_present = 0;
|
||||
mwi_activate->originating_number.length = 0;
|
||||
mwi_activate->timestamp_present = 0;
|
||||
mwi_activate->priority_present = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
ASN1_CALL(pos, rose_dec_qsig_MsgCentreId(ctrl, "msgCentreId", tag, pos,
|
||||
seq_end, &mwi_activate->msg_centre_id));
|
||||
mwi_activate->msg_centre_id_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "nbOfMessages", tag, pos, seq_end,
|
||||
&value));
|
||||
mwi_activate->number_of_messages = value;
|
||||
mwi_activate->number_of_messages_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
/* Remove EXPLICIT tag */
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
||||
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "originatingNr", tag, pos,
|
||||
explicit_end, &mwi_activate->originating_number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
||||
break;
|
||||
case ASN1_TYPE_GENERALIZED_TIME:
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "timestamp", tag, pos, end,
|
||||
sizeof(mwi_activate->timestamp), mwi_activate->timestamp, &str_len));
|
||||
mwi_activate->timestamp_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "priority", tag, pos, seq_end, &value));
|
||||
mwi_activate->priority = value;
|
||||
mwi_activate->priority_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 6:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExt %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG MWIDeactivate invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_MWIDeactivate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigMWIDeactivateArg *mwi_deactivate;
|
||||
|
||||
mwi_deactivate = &args->qsig.MWIDeactivate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " MWIDeactivateArg %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "servedUserNr", tag, pos, seq_end,
|
||||
&mwi_deactivate->served_user_number));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
|
||||
mwi_deactivate->basic_service = value;
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
mwi_deactivate->msg_centre_id_present = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
ASN1_CALL(pos, rose_dec_qsig_MsgCentreId(ctrl, "msgCentreId", tag, pos,
|
||||
seq_end, &mwi_deactivate->msg_centre_id));
|
||||
mwi_deactivate->msg_centre_id_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExt %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG MWIInterrogate invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_MWIInterrogate_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
struct roseQsigMWIInterrogateArg *mwi_interrogate;
|
||||
|
||||
mwi_interrogate = &args->qsig.MWIInterrogate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " MWIInterrogateArg %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "servedUserNr", tag, pos, seq_end,
|
||||
&mwi_interrogate->served_user_number));
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
|
||||
mwi_interrogate->basic_service = value;
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
mwi_interrogate->msg_centre_id_present = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
ASN1_CALL(pos, rose_dec_qsig_MsgCentreId(ctrl, "msgCentreId", tag, pos,
|
||||
seq_end, &mwi_interrogate->msg_centre_id));
|
||||
mwi_interrogate->msg_centre_id_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExt %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the MWIInterrogateResElt argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param record Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_qsig_MWIInterrogateResElt(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigMWIInterrogateResElt *record)
|
||||
{
|
||||
int32_t value;
|
||||
size_t str_len;
|
||||
int length;
|
||||
int seq_offset;
|
||||
int explicit_offset;
|
||||
const unsigned char *explicit_end;
|
||||
const unsigned char *seq_end;
|
||||
const unsigned char *save_pos;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " MWIInterrogateResElt %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
|
||||
record->basic_service = value;
|
||||
|
||||
/*
|
||||
* A sequence specifies an ordered list of component types.
|
||||
* However, for simplicity we are not checking the order of
|
||||
* the remaining optional components.
|
||||
*/
|
||||
record->msg_centre_id_present = 0;
|
||||
record->number_of_messages_present = 0;
|
||||
record->originating_number.length = 0;
|
||||
record->timestamp_present = 0;
|
||||
record->priority_present = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
save_pos = pos;
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
ASN1_CALL(pos, rose_dec_qsig_MsgCentreId(ctrl, "msgCentreId", tag, pos,
|
||||
seq_end, &record->msg_centre_id));
|
||||
record->msg_centre_id_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "nbOfMessages", tag, pos, seq_end,
|
||||
&value));
|
||||
record->number_of_messages = value;
|
||||
record->number_of_messages_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
/* Remove EXPLICIT tag */
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
||||
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "originatingNr", tag, pos,
|
||||
explicit_end, &record->originating_number));
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
||||
break;
|
||||
case ASN1_TYPE_GENERALIZED_TIME:
|
||||
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "timestamp", tag, pos, end,
|
||||
sizeof(record->timestamp), record->timestamp, &str_len));
|
||||
record->timestamp_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "priority", tag, pos, seq_end, &value));
|
||||
record->priority = value;
|
||||
record->priority_present = 1;
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 6:
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " argumentExt %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
/* Fixup will skip over the manufacturer extension information */
|
||||
default:
|
||||
pos = save_pos;
|
||||
goto cancel_options;
|
||||
}
|
||||
}
|
||||
cancel_options:;
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG MWIInterrogate result argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_MWIInterrogate_RES(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
struct roseQsigMWIInterrogateRes *mwi_interrogate;
|
||||
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " MWIInterrogateRes %s\n", asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
mwi_interrogate = &args->qsig.MWIInterrogate;
|
||||
|
||||
mwi_interrogate->num_records = 0;
|
||||
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
||||
if (mwi_interrogate->num_records < ARRAY_LEN(mwi_interrogate->list)) {
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
||||
ASN1_CALL(pos, rose_dec_qsig_MWIInterrogateResElt(ctrl, "listEntry", tag,
|
||||
pos, seq_end, &mwi_interrogate->list[mwi_interrogate->num_records]));
|
||||
++mwi_interrogate->num_records;
|
||||
} else {
|
||||
/* Too many records */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_qsig_mwi.c */
|
||||
474
rose_qsig_name.c
Normal file
474
rose_qsig_name.c
Normal file
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
* libpri: An implementation of Primary Rate ISDN
|
||||
*
|
||||
* Copyright (C) 2009 Digium, Inc.
|
||||
*
|
||||
* Richard Mudgett <rmudgett@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*
|
||||
* In addition, when this program is distributed with Asterisk in
|
||||
* any form that would qualify as a 'combined work' or as a
|
||||
* 'derivative work' (but not mere aggregation), you can redistribute
|
||||
* and/or modify the combination under the terms of the license
|
||||
* provided with that copy of Asterisk, instead of the license
|
||||
* terms granted here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file
|
||||
* \brief Q.SIG ROSE Name operations and elements
|
||||
*
|
||||
* Name-Operations ECMA-164 Annex C
|
||||
*
|
||||
* \author Richard Mudgett <rmudgett@digium.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "libpri.h"
|
||||
#include "pri_internal.h"
|
||||
#include "rose.h"
|
||||
#include "rose_internal.h"
|
||||
#include "asn1.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the Q.SIG NameSet type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param tag Component tag to identify the encoded component.
|
||||
* The tag should be ASN1_TAG_SEQUENCE unless the caller
|
||||
* implicitly tags it otherwise.
|
||||
* \param name
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *rose_enc_qsig_NameSet(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, unsigned tag, const struct roseQsigName *name)
|
||||
{
|
||||
unsigned char *seq_len;
|
||||
|
||||
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
||||
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_TYPE_OCTET_STRING, name->data,
|
||||
name->length));
|
||||
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, name->char_set));
|
||||
|
||||
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG Name type.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param name
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_Name(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct roseQsigName *name)
|
||||
{
|
||||
switch (name->presentation) {
|
||||
case 0: /* optional_name_not_present */
|
||||
/* Do not encode anything */
|
||||
break;
|
||||
case 1: /* presentation_allowed */
|
||||
if (name->char_set == 1) {
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
||||
name->data, name->length));
|
||||
} else {
|
||||
ASN1_CALL(pos, rose_enc_qsig_NameSet(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 1, name));
|
||||
}
|
||||
break;
|
||||
case 2: /* presentation_restricted */
|
||||
if (name->char_set == 1) {
|
||||
ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
|
||||
name->data, name->length));
|
||||
} else {
|
||||
ASN1_CALL(pos, rose_enc_qsig_NameSet(ctrl, pos, end,
|
||||
ASN1_CLASS_CONTEXT_SPECIFIC | 3, name));
|
||||
}
|
||||
break;
|
||||
case 3: /* presentation_restricted_null */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 7));
|
||||
break;
|
||||
case 4: /* name_not_available */
|
||||
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4));
|
||||
break;
|
||||
default:
|
||||
ASN1_ENC_ERROR(ctrl, "Unknown name presentation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the Q.SIG party-Name invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param party Information to encode.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *rose_enc_qsig_PartyName_ARG_Backend(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, const struct roseQsigPartyName_ARG *party)
|
||||
{
|
||||
return rose_enc_qsig_Name(ctrl, pos, end, &party->name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CallingName invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CallingName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.CallingName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG CalledName invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_CalledName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.CalledName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG ConnectedName invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end,
|
||||
&args->qsig.ConnectedName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode the Q.SIG BusyName invoke facility ie arguments.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode ASN.1 component.
|
||||
* \param end End of ASN.1 encoding data buffer.
|
||||
* \param args Arguments to encode in the buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
unsigned char *rose_enc_qsig_BusyName_ARG(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.BusyName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the Q.SIG NameData Name argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param fname Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param name Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_qsig_NameData(struct pri *ctrl, const char *fname,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigName *name)
|
||||
{
|
||||
size_t str_len;
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_string_bin(ctrl, fname, tag, pos, end, sizeof(name->data),
|
||||
name->data, &str_len));
|
||||
name->length = str_len;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the Q.SIG NameSet Name argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param fname Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param name Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_qsig_NameSet(struct pri *ctrl, const char *fname,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigName *name)
|
||||
{
|
||||
int32_t value;
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s NameSet %s\n", fname, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_TYPE_OCTET_STRING);
|
||||
ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "nameData", tag, pos, seq_end, name));
|
||||
|
||||
if (pos < end && *pos != ASN1_INDEF_TERM) {
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
|
||||
ASN1_CALL(pos, asn1_dec_int(ctrl, "characterSet", tag, pos, seq_end, &value));
|
||||
name->char_set = value;
|
||||
} else {
|
||||
name->char_set = 1; /* default to iso8859-1 */
|
||||
}
|
||||
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG Name argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for any diagnostic messages.
|
||||
* \param fname Field name
|
||||
* \param tag Component tag that identified this production.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param name Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_Name(struct pri *ctrl, const char *fname,
|
||||
unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigName *name)
|
||||
{
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s Name\n", fname);
|
||||
}
|
||||
name->char_set = 1; /* default to iso8859-1 */
|
||||
switch (tag & ~ASN1_PC_MASK) {
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
||||
name->presentation = 1; /* presentation_allowed */
|
||||
ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "namePresentationAllowedSimple", tag,
|
||||
pos, end, name));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
name->presentation = 1; /* presentation_allowed */
|
||||
ASN1_CALL(pos, rose_dec_qsig_NameSet(ctrl, "namePresentationAllowedExtended",
|
||||
tag, pos, end, name));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
|
||||
name->presentation = 2; /* presentation_restricted */
|
||||
ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "namePresentationRestrictedSimple",
|
||||
tag, pos, end, name));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
|
||||
/* Must be constructed but we will not check for it for simplicity. */
|
||||
name->presentation = 2; /* presentation_restricted */
|
||||
ASN1_CALL(pos, rose_dec_qsig_NameSet(ctrl, "namePresentationRestrictedExtended",
|
||||
tag, pos, end, name));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
name->presentation = 4; /* name_not_available */
|
||||
name->length = 0;
|
||||
name->data[0] = 0;
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "nameNotAvailable", tag, pos, end));
|
||||
break;
|
||||
case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
|
||||
/* Must not be constructed but we will not check for it for simplicity. */
|
||||
name->presentation = 3; /* presentation_restricted_null */
|
||||
name->length = 0;
|
||||
name->data[0] = 0;
|
||||
ASN1_CALL(pos, asn1_dec_null(ctrl, "namePresentationRestrictedNull", tag, pos,
|
||||
end));
|
||||
break;
|
||||
default:
|
||||
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the Q.SIG party-Name invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param name Field name
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param party Parameter storage to fill.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static const unsigned char *rose_dec_qsig_PartyName_ARG_Backend(struct pri *ctrl,
|
||||
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
||||
struct roseQsigPartyName_ARG *party)
|
||||
{
|
||||
int length;
|
||||
int seq_offset;
|
||||
const unsigned char *seq_end;
|
||||
|
||||
if (tag == ASN1_TAG_SEQUENCE) {
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
|
||||
}
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "name", tag, pos, seq_end,
|
||||
&party->name));
|
||||
|
||||
/* Fixup will skip over any OPTIONAL manufacturer extension information */
|
||||
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
||||
} else {
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, name, tag, pos, end, &party->name));
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CallingName invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CallingName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "callingName", tag, pos, end,
|
||||
&args->qsig.CallingName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG CalledName invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_CalledName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "calledName", tag, pos, end,
|
||||
&args->qsig.CalledName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG ConnectedName invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "connectedName", tag, pos, end,
|
||||
&args->qsig.ConnectedName);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Decode the Q.SIG BusyName invoke argument parameters.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param tag Component tag that identified this structure.
|
||||
* \param pos Starting position of the ASN.1 component length.
|
||||
* \param end End of ASN.1 decoding data buffer.
|
||||
* \param args Arguments to fill in from the decoded buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
const unsigned char *rose_dec_qsig_BusyName_ARG(struct pri *ctrl, unsigned tag,
|
||||
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
||||
{
|
||||
return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "busyName", tag, pos, end,
|
||||
&args->qsig.BusyName);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end rose_qsig_name.c */
|
||||
2473
rosetest.c
Normal file
2473
rosetest.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user