Compare commits

..

2 Commits

Author SHA1 Message Date
Kevin P. Fleming
182e49bb99 Importing files for 1.4.7 release
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.7@615 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-08-05 22:35:33 +00:00
Kevin P. Fleming
954bdb25aa Creating tag for the release of libpri-1.4.7
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.7@614 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2008-08-05 22:34:47 +00:00
33 changed files with 4946 additions and 34875 deletions

View File

@@ -1 +1 @@
1.4.11
1.4.7

746
ChangeLog
View File

@@ -1,749 +1,3 @@
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.
2009-01-09 17:58 +0000 [r656] Matthew Fredrickson <creslin@digium.com>
* q921.c: Add additional case where T200 expires greater than N200
times and we need to release and reacquire the TEI.
2008-12-23 21:38 +0000 [r653] Matthew Fredrickson <creslin@digium.com>
* q921.c, q931.c: Add some additional debug for Q.921 MDL messages
as well as fix a bug in RESTART messages on BRI
2008-11-22 Matthew Fredrickson <creslin@digium.com>
* libpri 1.4.8 released.
2008-11-22 00:34 +0000 [r645] Matthew Fredrickson <creslin@digium.com>
* q921.c: Fix a number of Q.921 bugs, found doing TBR4 compliance
testing, thanks to Tzafrir, Xorcom, and co. (#12861). Thanks!
2008-10-17 16:13 +0000 [r636] Matthew Fredrickson <creslin@digium.com>
* pri.c, pri_internal.h, pri_q931.h, q931.c, pri_facility.c,
pri_facility.h, libpri.h: Merging in additional Q.SIG features in
#13454. Includes Q.SIG physical/logical channel mapping support,
extended coding of Q.SIG name operations (calling name), and call
rerouting support via added dialplan application.
2008-08-06 18:20 +0000 [r616] Jason Parker <jparker@digium.com>
* Makefile: Make install paths use libdir, like libss7
2008-08-05 Kevin P. Fleming <kpfleming@digium.com>
* libpri 1.4.7 released.

View File

@@ -41,55 +41,14 @@ 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 \
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)
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)
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 XGNUX))
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX))
LDCONFIG_FLAGS=-n
else
ifeq (${OSARCH},FreeBSD)
@@ -114,14 +73,7 @@ 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
LIBPRI_OPT = -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
else
LIBPRI_OPT = -O2
endif
ifeq ($(CPUARCH),i686)
CFLAGS += -m32
SOFLAGS += -m32
CFLAGS += -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
endif
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
@@ -144,27 +96,27 @@ update:
fi
install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
mkdir -p $(INSTALL_PREFIX)$(libdir)
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/include
ifneq (${OSARCH},SunOS)
install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
#if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(libdir)/$(DYNAMIC_LIBRARY); fi
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib; fi
else
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
install -f $(INSTALL_PREFIX)$(libdir) -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -f $(INSTALL_PREFIX)$(libdir) -m 644 $(STATIC_LIBRARY)
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 644 $(STATIC_LIBRARY)
endif
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.a
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.a
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
pritest: pritest.o
@@ -179,9 +131,6 @@ 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
View File

@@ -1,257 +0,0 @@
/*
* 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 */

File diff suppressed because it is too large Load Diff

View File

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

788
libpri.h

File diff suppressed because it is too large Load Diff

1075
pri.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,21 +31,120 @@
#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_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
@@ -67,111 +166,137 @@ struct rose_msg_reject;
#define Q932_TON_SUBSCRIBER 0x04
#define Q932_TON_ABBREVIATED 0x06
/* 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
/* RLT related Operations */
#define RLT_SERVICE_ID 0x3e
#define RLT_OPERATION_IND 0x01
#define RLT_THIRD_PARTY 0x02
/*! 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,
struct rose_component {
u_int8_t type;
u_int8_t len;
u_int8_t data[0];
};
union apdu_msg_data {
const struct rose_msg_result *result;
const struct rose_msg_error *error;
const struct rose_msg_reject *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_callback_param {
void *ptr;
long value;
char pad[8];
};
#define NEXT_COMPONENT(component, idx) \
(idx) += (component)->len + 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 SUB_COMPONENT(component, idx) \
(idx) += 2
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];
};
#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);
/* 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);
@@ -181,32 +306,20 @@ 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);
extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
/* 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 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);
/* Used by q931.c to cleanup the apdu queue upon destruction of a call */
int pri_call_apdu_queue_cleanup(q931_call *call);
/* Adds the "standard" APDUs to a call */
int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
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);
int asn1_dump(struct pri *pri, void *comp, int len);
#endif /* _PRI_FACILITY_H */

View File

@@ -32,45 +32,30 @@
#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;
};
/*! Maximum number of scheduled events active at the same time. */
struct q921_frame;
enum q931_state;
enum q931_mode;
/* No more than 128 scheduled events */
#define MAX_SCHED 128
/*! Maximum number of facility ie's to handle per incoming message. */
#define MAX_FACILITY_IES 8
#define MAX_TIMERS 32
/*! 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 */
@@ -86,51 +71,38 @@ 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 RC;
int peer_rx_busy:1;
int own_rx_busy:1;
int acknowledge_pending:1;
int reject_exception:1;
int window; /* Max window size */
int windowlen; /* Fullness of window */
int v_s; /* Next N(S) for transmission */
int v_a; /* Last acknowledged frame */
int v_r; /* Next frame expected to be received */
int v_na; /* What we've told our peer we've acknowledged */
int solicitfbit; /* Have we sent an I or S frame with the F-bit set? */
int retrans; /* Retransmissions */
int sentrej; /* Are we in reject state */
int cref; /* Next call reference value */
int l3initiated;
int busy; /* Peer is busy */
/* 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[PRI_MAX_TIMERS];
int timers[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;
@@ -139,12 +111,8 @@ struct pri {
q931_call **callpool;
q931_call *localpool;
/*!
* \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;
/* do we do overlap dialing */
int overlapdial;
#ifdef LIBPRI_COUNTERS
/* q921/q931 packet counters */
@@ -154,226 +122,52 @@ struct pri {
unsigned int q931_rxcount;
#endif
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;
unsigned char last_invoke; /* Last ROSE invoke ID */
unsigned char sendfacility;
};
/*! \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;
struct q931_party_redirecting redirecting;
struct q931_party_id caller;
struct q931_party_address called;
char *caller;
int callerplan;
char *callername;
int callerpres;
char *called;
int calledplan;
int userl1;
int numcomplete;
int cis_call;
int cis_auto_disconnect;
char *redirectingnum;
int redirectingplan;
int redirectingpres;
int redirectingreason;
int justsignalling;
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
#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,
struct apdu_event {
int message; /* What message to send the ADPU in */
void (*callback)(void *data); /* Callback function for when response is received */
void *data; /* Data to callback */
unsigned char apdu[255]; /* ADPU to send */
int apdu_len; /* Length of ADPU */
int sent; /* Have we been sent already? */
struct apdu_event *next; /* Linked list pointer */
};
/* q931_call datastructure */
struct q931_call {
struct pri *pri; /* PRI */
int cr; /* Call Reference */
int forceinvert; /* Force inversion of call number even if 0 */
q931_call *next;
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
int slotmap;
@@ -402,142 +196,71 @@ struct q931_call {
int userl2;
int userl3;
int rateadaption;
/*!
* \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 sentchannel;
int justsignalling; /* for a signalling-only connection */
int progcode; /* Progress coding */
int progloc; /* Progress Location */
int progress; /* Progress indicator */
int progressmask; /* Progress Indicator bitmask */
int notify; /* Notification indicator. */
int notify; /* Notification */
int causecode; /* Cause Coding */
int causeloc; /* Cause Location */
int cause; /* Cause of clearing */
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 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 */
int ani2; /* ANI II */
/*! 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 calledplan;
int nonisdn;
char callednum[256]; /* Called Number */
int complete; /* no more digits coming */
int newcall; /* if the received message has a new call reference value */
int retranstimer; /* Timer for retransmitting DISC */
int t308_timedout; /* Whether t308 timed out once */
struct q931_party_redirecting redirecting;
int redirectingplan;
int redirectingpres;
int redirectingreason;
char redirectingnum[256]; /* Number of redirecting party */
char redirectingname[256]; /* Name of redirecting party */
/*! \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;
/* Filled in cases of multiple diversions */
int origcalledplan;
int origcalledpres;
int origredirectingreason; /* Original reason for redirect (in cases of multiple redirects) */
char origcalledname[256]; /* Original name of person being called */
char origcallednum[256]; /* Orignal number of person being called */
int useruserprotocoldisc;
char useruserinfo[256];
char callingsubaddr[256]; /* Calling parties sub address */
long aoc_units; /* Advice of Charge Units */
struct apdu_event *apdus; /* APDU queue for call */
int transferable; /* RLT call is transferable */
int transferable;
unsigned int rlt_call_id; /* RLT call id */
/* Bridged call info */
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;
q931_call *bridged_call; /* Pointer to other leg of bridged call */
};
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
@@ -548,187 +271,14 @@ extern void pri_schedule_del(struct pri *pri, int ev);
extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
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)));
extern void pri_message(struct pri *pri, char *fmt, ...);
extern void pri_error(struct pri *pri, char *fmt, ...);
void libpri_copy_string(char *dst, const char *src, size_t size);
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

View File

@@ -166,41 +166,30 @@ 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 {
/* 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_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
} 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);
extern void q921_start(struct pri *pri, int now);
//extern void q921_reset(struct pri *pri, int reset_iqueue);
extern void q921_reset(struct pri *pri);
extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
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);
extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr);
#endif

View File

@@ -30,6 +30,44 @@
#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,
@@ -41,13 +79,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;/*!< Call reference length */
u_int8_t crlen:4;
#else
u_int8_t crlen:4;/*!< Call reference length */
u_int8_t crlen:4;
u_int8_t x0:4;
#endif
u_int8_t contents[0];
u_int8_t crv[3];/*!< Call reference value */
u_int8_t crv[3];
} __attribute__ ((packed)) q931_h;
@@ -75,10 +113,6 @@ 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 */
@@ -123,16 +157,8 @@ typedef struct q931_ie {
#define Q931_SUSPEND_REJECT 0x21
/* Maintenance messages (codeset 0 only) */
#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 */
#define NATIONAL_SERVICE 0x0f
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x07
/* Special codeset 0 IE */
#define NATIONAL_CHANGE_STATUS 0x1
@@ -142,11 +168,10 @@ typedef struct q931_ie {
#define Q931_NON_LOCKING_SHIFT 0x98
#define Q931_BEARER_CAPABILITY 0x04
#define Q931_CAUSE 0x08
#define Q931_IE_CALL_STATE 0x14
#define Q931_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
@@ -175,9 +200,8 @@ 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_SUBADDR 0x4d
#define Q931_IE_CONNECTED_ADDR 0x0C
#define Q931_IE_CONNECTED_NUM 0x4C
#define Q931_IE_CALL_IDENTITY 0x10
#define Q931_IE_FACILITY 0x1c
#define Q931_IE_ENDPOINT_ID 0x26
@@ -200,264 +224,38 @@ typedef struct q931_ie {
#define Q931_IE_ESCAPE_FOR_EXT 0x7F
/*! 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,
};
/* 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 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, int tei, q931_h *h, int len);
extern int q931_receive(struct pri *pri, q931_h *h, int len);
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_call_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause);
extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);
@@ -468,7 +266,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, const char *digits);
extern int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits);
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
@@ -486,22 +284,13 @@ 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);
struct q931_call *q931_find_call(struct pri *ctrl, int cr);
struct q931_call *q931_new_call(struct pri *pri);
extern q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
void q931_destroycall(struct pri *pri, q931_call *c);
extern 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 Normal file
View File

@@ -0,0 +1,97 @@
/*
* 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

View File

@@ -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, h->h.tei, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
q931_dump(pri, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
}
fflush(stdout);
fflush(stderr);

View File

@@ -33,43 +33,25 @@
#include "pri_internal.h"
/*! \brief The maximum number of timers that were active at once. */
static int maxsched = 0;
/* Scheduler routines */
/*!
* \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 pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data)
{
int x;
struct timeval tv;
/* 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) {
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(ctrl, "No more room in scheduler\n");
return 0;
}
if (x >= maxsched) {
maxsched = x + 1;
pri_error(pri, "No more room in scheduler\n");
return -1;
}
if (x > maxsched)
maxsched = x;
gettimeofday(&tv, NULL);
tv.tv_sec += ms / 1000;
tv.tv_usec += (ms % 1000) * 1000;
@@ -77,110 +59,71 @@ int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), v
tv.tv_usec -= 1000000;
tv.tv_sec += 1;
}
ctrl->pri_sched[x].when = tv;
ctrl->pri_sched[x].callback = function;
ctrl->pri_sched[x].data = data;
return x + 1;
pri->pri_sched[x].when = tv;
pri->pri_sched[x].callback = function;
pri->pri_sched[x].data = data;
return x;
}
/*!
* \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 *pri_schedule_next(struct pri *pri)
{
struct timeval *closest = NULL;
int x;
/* 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;
}
/* 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;
}
return closest;
}
/*!
* \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)
static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
{
int x;
void (*callback)(void *);
void *data;
/* 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 && ((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;
}
pri_event *e;
if (pri->subchannel) {
if ((e = __pri_schedule_run(pri->subchannel, tv))) {
return e;
}
}
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
((pri->pri_sched[x].when.tv_sec < tv->tv_sec) ||
((pri->pri_sched[x].when.tv_sec == tv->tv_sec) &&
(pri->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
pri->schedev = 0;
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;
}
}
return NULL;
}
/*!
* \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)
pri_event *pri_schedule_run(struct pri *pri)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return __pri_schedule_run(ctrl, &tv);
return __pri_schedule_run(pri, &tv);
}
/*!
* \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)
void pri_schedule_del(struct pri *pri,int id)
{
/* 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);
}
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;
}

2115
q921.c

File diff suppressed because it is too large Load Diff

6256
q931.c

File diff suppressed because it is too large Load Diff

2464
rose.c

File diff suppressed because it is too large Load Diff

3580
rose.h

File diff suppressed because it is too large Load Diff

View File

@@ -1,983 +0,0 @@
/*
* 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 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,332 +0,0 @@
/*
* 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 */

View File

@@ -1,477 +0,0 @@
/*
* 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 */

View File

@@ -1,277 +0,0 @@
/*
* 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 */

View File

@@ -1,100 +0,0 @@
/*
* 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,883 +0,0 @@
/*
* 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,790 +0,0 @@
/*
* 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 */

View File

@@ -1,474 +0,0 @@
/*
* 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

File diff suppressed because it is too large Load Diff