Compare commits

..

4 Commits

Author SHA1 Message Date
Kevin P. Fleming
1f98766ae2 remove CVS ignore lists
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.0@267 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 18:40:06 +00:00
Kevin P. Fleming
b45e8995c7 remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.0@266 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 18:39:18 +00:00
Kevin P. Fleming
316cf41fc7 automatic tag renames
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.0@263 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-27 04:17:23 +00:00
Admin Commit
c747aadbea This commit was manufactured by cvs2svn to create tag 'v1-0-0'.
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/v1-0-0@136 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-20 13:29:37 +00:00
61 changed files with 2987 additions and 63672 deletions

View File

@@ -1 +0,0 @@
0

12
.gitignore vendored
View File

@@ -1,12 +0,0 @@
*.o
*.o.d
*.lo
*.so
*.a
libpri.so.*
pridump
pritest
rosetest
testprilib
version.c

View File

@@ -1,4 +0,0 @@
[gerrit]
host=gerrit.asterisk.org
port=29418
project=libpri.git

16
ChangeLog Normal file
View File

@@ -0,0 +1,16 @@
libpri 0.3.0
-- Fix talking to switch
-- Add pri dump
-- Add test application
-- Fix strncpy stuff
libpri 0.1.2
-- Added PRI_EVENT_HANGUP_ACK so you can know when the disconnect was
acknowledged
libpri 0.1.1
-- Added PRI_DEBUG_Q931_ANOMALY flag so that certain non-error-related
messages would not be output unless specifically desired.
libpri 0.1.0
-- Initial release

341
LICENSE
View File

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

210
Makefile
View File

@@ -10,214 +10,106 @@
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
# Uncomment if you want libpri not send PROGRESS_INDICATOR w/ALERTING
#ALERTING=-DALERTING_NO_PROGRESS
CC=gcc
GREP=grep
AWK=awk
AR=ar
RANLIB=ranlib
# Uncomment if you want libpri to count number of Q921/Q931 sent/received
#LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
OSARCH=$(shell uname -s)
PROC?=$(shell uname -m)
# SONAME version; should be changed on every ABI change
# please don't change it needlessly; it's perfectly fine to have a SONAME
# of 1.2 and a version of 1.4.x
SONAME:=1.4
PROC=$(shell uname -m)
TOBJS=testpri.o
T2OBJS=testprilib.o
STATIC_LIBRARY=libpri.a
DYNAMIC_LIBRARY:=libpri.so.$(SONAME)
STATIC_OBJS= \
copy_string.o \
pri.o \
q921.o \
prisched.o \
q931.o \
pri_aoc.o \
pri_cc.o \
pri_facility.o \
asn1_primitive.o \
rose.o \
rose_address.o \
rose_etsi_aoc.o \
rose_etsi_cc.o \
rose_etsi_diversion.o \
rose_etsi_ect.o \
rose_etsi_mwi.o \
rose_other.o \
rose_q931.o \
rose_qsig_aoc.o \
rose_qsig_cc.o \
rose_qsig_ct.o \
rose_qsig_diversion.o \
rose_qsig_mwi.o \
rose_qsig_name.o \
version.o
DYNAMIC_OBJS= \
$(STATIC_OBJS)
CFLAGS ?= -g
CFLAGS += $(CPPFLAGS)
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
INSTALL_PREFIX=$(DESTDIR)
INSTALL_BASE=/usr
libdir?=$(INSTALL_BASE)/lib
ifneq ($(findstring Darwin,$(OSARCH)),)
SOFLAGS=$(LDFLAGS) -dynamic -bundle -Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace
ifeq ($(shell /usr/bin/sw_vers -productVersion | cut -c1-4),10.6)
SOFLAGS+=/usr/lib/bundle1.o
endif
LDCONFIG=/usr/bin/true
else
SOFLAGS=$(LDFLAGS) -shared -Wl,-h$(DYNAMIC_LIBRARY) $(COVERAGE_LDFLAGS)
LDCONFIG = /sbin/ldconfig
endif
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX XGNUX))
DYNAMIC_LIBRARY=libpri.so.1.0
STATIC_OBJS=pri.o q921.o prisched.o q931.o
DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
INSTALL_PREFIX=
ifeq (${OSARCH},Linux)
LDCONFIG_FLAGS=-n
else
ifeq (${OSARCH},FreeBSD)
LDCONFIG_FLAGS=-m
CFLAGS += -I../zaptel -I../zapata
INSTALL_BASE=/usr/local
endif
endif
ifeq (${OSARCH},SunOS)
CFLAGS += -DSOLARIS -I../zaptel-solaris
LDCONFIG =
LDCONFIG_FLAGS = \# # Trick to comment out the period in the command below
#INSTALL_PREFIX = /opt/asterisk # Uncomment out to install in standard Solaris location for 3rd party code
endif
UTILITIES= pridump pritest rosetest testprilib
export PRIVERSION
PRIVERSION:=$(shell GREP=$(GREP) AWK=$(AWK) build_tools/make_version .)
#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
#This works for even old (2.96) versions of gcc and provides a small boost either way.
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesnt support it.
ifeq ($(PROC),sparc64)
PROC=ultrasparc
LIBPRI_OPT = -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
else
ifneq ($(CODE_COVERAGE),)
LIBPRI_OPT=
COVERAGE_CFLAGS=-ftest-coverage -fprofile-arcs
COVERAGE_LDFLAGS=-ftest-coverage -fprofile-arcs
else
LIBPRI_OPT=-O2
endif
CFLAGS += -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
endif
ifeq ($(CPUARCH),i686)
CFLAGS += -m32
SOFLAGS += -m32
endif
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY) $(UTILITIES)
all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
update:
@if [ -d .svn ]; then \
echo "Updating from Subversion..." ; \
fromrev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
svn update | tee update.out; \
torev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
echo "`date` Updated from revision $${fromrev} to $${torev}." >> update.log; \
rm -f .version; \
if [ `grep -c ^C update.out` -gt 0 ]; then \
echo ; echo "The following files have conflicts:" ; \
grep ^C update.out | cut -b4- ; \
fi ; \
rm -f update.out; \
else \
echo "Not under version control"; \
fi
@echo "Updating from CVS"
@cvs update -d
install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
mkdir -p $(INSTALL_PREFIX)$(libdir)
mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/include
ifneq (${OSARCH},SunOS)
install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(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 $(DYNAMIC_LIBRARY) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
else
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
install -f $(INSTALL_PREFIX)$(libdir) -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf $(DYNAMIC_LIBRARY) libpri.so)
install -f $(INSTALL_PREFIX)$(libdir) -m 644 $(STATIC_LIBRARY)
endif
mkdir -p $(INSTALL_PREFIX)/usr/lib
mkdir -p $(INSTALL_PREFIX)/usr/include
install -m 644 libpri.h $(INSTALL_PREFIX)/usr/include
install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)/usr/lib
( cd $(INSTALL_PREFIX)/usr/lib ; ln -sf libpri.so.1 libpri.so )
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)/usr/lib
/sbin/ldconfig
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)$(libdir)/$(STATIC_LIBRARY)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so
rm -f $(INSTALL_PREFIX)$(libdir)/$(DYNAMIC_LIBRARY)
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.so.1.0
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.so
rm -f $(INSTALL_PREFIX)/usr/lib/libpri.a
rm -f $(INSTALL_PREFIX)/usr/include/libpri.h
pritest: pritest.o $(STATIC_LIBRARY)
$(CC) -o $@ $< $(STATIC_LIBRARY) $(CFLAGS)
pritest: pritest.o
$(CC) -o pritest pritest.o -L. -lpri -lzap $(CFLAGS)
testprilib.o: testprilib.c
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE $(MAKE_DEPS) -c -o $@ $<
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE -o $@ -c $<
testprilib: testprilib.o $(STATIC_LIBRARY)
$(CC) -o $@ $< $(STATIC_LIBRARY) -lpthread $(CFLAGS)
testprilib: testprilib.o
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
pridump: pridump.o $(DYNAMIC_LIBRARY)
$(CC) -o $@ $< -L. -lpri $(CFLAGS)
pridump: pridump.o
$(CC) -o pridump pridump.o -L. -lpri -lzap $(CFLAGS)
rosetest: rosetest.o $(STATIC_LIBRARY)
$(CC) -o $@ $< $(STATIC_LIBRARY) $(CFLAGS)
include .depend
MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
%.o: %.c
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
%.lo: %.c
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
%.lo : %.c
$(CC) -fPIC $(CFLAGS) -o $@ -c $<
$(STATIC_LIBRARY): $(STATIC_OBJS)
$(AR) rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
$(RANLIB) $(STATIC_LIBRARY)
ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
ranlib $(STATIC_LIBRARY)
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
$(CC) $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
$(LDCONFIG) $(LDCONFIG_FLAGS) .
ln -sf $(DYNAMIC_LIBRARY) libpri.so
version.c: FORCE
@build_tools/make_version_c > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
$(CC) -shared -Wl,-soname,libpri.so.1 -o $@ $(DYNAMIC_OBJS)
/sbin/ldconfig $(LDCONFIG_FLAGS) .
ln -sf libpri.so.1 libpri.so
clean:
rm -f *.o *.so *.lo
rm -f $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f $(UTILITIES)
rm -f .*.d
rm -f *.o *.so *.lo *.so.1 *.so.1.0
rm -f testpri testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f pritest pridump
rm -f .depend
.PHONY:
depend: .depend
FORCE:
ifneq ($(wildcard .*.d),)
include .*.d
endif
.depend:
./mkdep ${CFLAGS} `ls *.c`

30
README
View File

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

4
TODO
View File

@@ -1,8 +1,10 @@
General:
-- D-Channel Backup
-- Test against 4e
Q.921:
-- Support unnumbered information frames
-- Get TEI codes working for BRI interfaces
Q.931:
-- Locking Shift IE
-- Implement the 11 missing Q.931 timers

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,79 +0,0 @@
#!/bin/sh
if [ -f ${1}/.version ]; then
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
TEAM=0
TAG=0
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 ${INTEGRATED} ${1} | cut -d: -f1`
if [ "${PARTS}" = "trunk" ] ; then
echo SVN-trunk-r${REV}
exit 0
fi
for PART in $PARTS ; do
if [ ${TAG} != 0 ] ; then
if [ "${PART}" = "autotag_for_be" ] ; then
continue
fi
if [ "${PART}" = "autotag_for_sx00i" ] ; then
continue
fi
RESULT="${PART}"
break
fi
if [ ${BRANCH} != 0 ] ; then
if [ -z "${RESULT}" ] ; then
RESULT="${PART}"
else
RESULT="${RESULT}-${PART}"
fi
break
fi
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}" = "tags" ] ; then
TAG=1
continue
fi
if [ "${PART}" = "team" ] ; then
TEAM=1
continue
fi
done
if [ ${TAG} != 0 ] ; then
echo ${RESULT}
else
echo SVN-${RESULT}-r${REV}${BASE:+-${BASE}}
fi
else
echo "UNKNOWN__and_probably_unsupported"
fi

View File

@@ -1,24 +0,0 @@
#!/bin/sh
if [ ! -f ../.flavor ]; then
EXTRA=""
else
aadkver=`cat ../.version`
aadkflavor=`cat ../.flavor`
EXTRA=" (${aadkflavor} ${aadkver})"
fi
cat << END
/*
* version.c
* Automatically generated
*/
#include "libpri.h"
static const char pri_version[] = "${PRIVERSION}${EXTRA}";
const char *pri_get_version(void)
{
return pri_version;
}
END

View File

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

View File

@@ -1,36 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Compiler-specific macros and other items
*
* Copyright (C) 2005, Digium, Inc.
*/
/*
* 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 _ASTERISK_COMPILER_H
#define _ASTERISK_COMPILER_H
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
#define __builtin_expect(exp, c) (exp)
#endif
#endif /* _ASTERISK_COMPILER_H */

View File

@@ -1,47 +0,0 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2005, 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.
*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "compiler.h"
#include "libpri.h"
#include "pri_internal.h"
void libpri_copy_string(char *dst, const char *src, size_t size)
{
while (*src && size) {
*dst++ = *src++;
size--;
}
if (__builtin_expect(!size, 0))
dst--;
*dst = '\0';
}

View File

@@ -1,376 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTMP agent.
*/
FSM CC_PTMP_Agent
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_PENDING_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_PENDING_AVAILABLE {
Stimulus CC_EVENT_MSG_ALERTING {
Action Send_CC_Available(Q931_ALERTING);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_MSG_DISCONNECT {
Action Send_CC_Available(Q931_DISCONNECT);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Release_LinkID;
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Release_LinkID;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_AVAILABLE {
Epilog {
Action Stop_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Epilog {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
}
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
/*
* Pass_Up_A_Status passes up the current final status of A.
* Does nothing if status is invalid.
*
* Pass_Up_A_Status_Indirect is the same as Pass_Up_A_Status but
* sets a timer to expire immediately to pass up the event.
* Does nothing if status is invalid.
*
* Pass_Up_Status_Rsp_A passes up the current accumulated status of A.
* Does nothing if status is invalid.
*
* Pass_Up_Status_Rsp_A_Indirect is the same as Pass_Up_Status_Rsp_A but
* sets a timer to expire immediately to pass up the event.
* Does nothing if status is invalid.
*/
State CC_STATE_ACTIVATED {
Prolog {
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
}
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_B_FREE {
Action Send_CCBSBFree;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
Test = Get_A_Status;
Test == Invalid {
Next_State CC_STATE_B_AVAILABLE;
}
Test == Busy {
Action Pass_Up_A_Status_Indirect;
Action Send_CCBSBFree;
Next_State CC_STATE_SUSPENDED;
}
Test == Free {
//Action Pass_Up_A_Status_Indirect;
Action Send_RemoteUserFree;
Next_State CC_STATE_WAIT_CALLBACK;
}
}
Stimulus CC_EVENT_A_STATUS {
Test = Get_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A_Indirect;
Next_State $;
}
Test != Active {
Action Reset_A_Status;
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Next_State $;
}
}
Stimulus CC_EVENT_A_FREE {
Action Raw_Status_Count_Reset;
Action Set_Raw_A_Status_Free;
Action Promote_Raw_A_Status;
Action Pass_Up_Status_Rsp_A;
Action Stop_T_CCBS1;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Action Pass_Up_Status_Rsp_A;
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Action Promote_Raw_A_Status;
Test = Get_A_Status;
Test != Invalid {
/* Only received User A busy. */
Action Raw_Status_Count_Reset;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
}
Stimulus CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1 {
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
}
}
State CC_STATE_B_AVAILABLE {
/* A status is always invalid on entry. */
Prolog {
Test = Get_T_CCBS1_Status;
Test != Active {
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
}
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_A_FREE {
Action Send_RemoteUserFree;
Action Set_Raw_A_Status_Free;
//Action Promote_Raw_A_Status;
//Action Pass_Up_A_Status;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Test = Get_Raw_A_Status;
Test != Invalid {
/* Only received User A is busy. */
Action Raw_Status_Count_Reset;
Action Send_CCBSBFree;
Action Promote_Raw_A_Status;
Action Pass_Up_A_Status;
Next_State CC_STATE_SUSPENDED;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
//Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
}
}
State CC_STATE_SUSPENDED {
Prolog {
Test = Get_T_CCBS1_Status;
Test != Active {
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
}
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_A_FREE {
Action Set_Raw_A_Status_Free;
Action Promote_Raw_A_Status;
Action Pass_Up_A_Status;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Test = Get_Raw_A_Status;
Test != Invalid {
/* Only received User A is busy. */
Action Raw_Status_Count_Reset;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
}
State CC_STATE_WAIT_CALLBACK {
Prolog {
/* Start T_CCBS3 */
Action Start_T_RECALL;
}
Epilog {
Action Stop_T_RECALL;
}
Stimulus CC_EVENT_TIMEOUT_T_RECALL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS3_TIMEOUT);
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_STOP_ALERTING {
/*
* If an earlier link can send us this event then we
* really should be configured for globalRecall like
* the earlier link.
*/
Test = Get_Recall_Mode;
Test == globalRecall {
Action Send_CCBSStopAlerting;
}
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
Test = Get_Recall_Mode;
Test == globalRecall {
Action Send_CCBSStopAlerting;
}
Next_State CC_STATE_CALLBACK;
}
Stimulus CC_EVENT_A_STATUS {
Action Set_Raw_A_Status_Free;
Action Pass_Up_Status_Rsp_A_Indirect;
}
}
State CC_STATE_CALLBACK {
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_AlreadyAccepted);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Set_Raw_A_Status_Free;
Action Pass_Up_Status_Rsp_A_Indirect;
}
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_B_AVAILABLE, CC_STATE_SUSPENDED, CC_STATE_WAIT_CALLBACK, CC_STATE_CALLBACK) {
Prolog {
/* Start T_CCBS2 or T_CCNR2 depending upon CC mode. */
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Next_State CC_STATE_IDLE;
}
}
Superstate CC_STATUS(CC_STATE_ACTIVATED, CC_STATE_B_AVAILABLE, CC_STATE_SUSPENDED) {
Epilog {
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
}
}
}

View File

@@ -1,494 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTMP agent.
*/
FSM CC_PTMP_Agent
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_PENDING_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_PENDING_AVAILABLE {
Stimulus CC_EVENT_MSG_ALERTING {
Action Send_CC_Available(Q931_ALERTING);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_MSG_DISCONNECT {
Action Send_CC_Available(Q931_DISCONNECT);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Release_LinkID;
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Release_LinkID;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_AVAILABLE {
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
Action Stop_T_RETENTION;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
Action Pass_Up_CC_Cancel;
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
/* Start T_CCBS2 or T_CCNR2 depending upon CC mode. */
Action Start_T_SUPERVISION;
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CANCEL {
Action Send_EraseCallLinkageID;
Action Release_LinkID;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
/*
* Pass_Up_A_Status passes up the current final status of A.
* Does nothing if status is invalid.
*
* Pass_Up_A_Status_Indirect is the same as Pass_Up_A_Status but
* sets a timer to expire immediately to pass up the event.
* Does nothing if status is invalid.
*
* Pass_Up_Status_Rsp_A passes up the current accumulated status of A.
* Does nothing if status is invalid.
*
* Pass_Up_Status_Rsp_A_Indirect is the same as Pass_Up_Status_Rsp_A but
* sets a timer to expire immediately to pass up the event.
* Does nothing if status is invalid.
*/
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_B_FREE {
Action Send_CCBSBFree;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
Test = Get_A_Status;
Test == Invalid {
Test = Get_T_CCBS1_Status;
Test != Active {
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
Next_State CC_STATE_B_AVAILABLE;
}
Test == Busy {
Action Pass_Up_A_Status_Indirect;
Action Send_CCBSBFree;
Test = Get_T_CCBS1_Status;
Test != Active {
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
Next_State CC_STATE_SUSPENDED;
}
Test == Free {
//Action Pass_Up_A_Status_Indirect;
Action Send_RemoteUserFree;
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
/* Start T_CCBS3 */
Action Start_T_RECALL;
Next_State CC_STATE_WAIT_CALLBACK;
}
}
Stimulus CC_EVENT_A_STATUS {
Test = Get_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A_Indirect;
Next_State $;
}
Test != Active {
Action Reset_A_Status;
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Next_State $;
}
}
Stimulus CC_EVENT_A_FREE {
Action Raw_Status_Count_Reset;
Action Set_Raw_A_Status_Free;
Action Promote_Raw_A_Status;
Action Pass_Up_Status_Rsp_A;
Action Stop_T_CCBS1;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Action Pass_Up_Status_Rsp_A;
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Action Promote_Raw_A_Status;
Test = Get_A_Status;
Test != Invalid {
/* Only received User A busy. */
Action Raw_Status_Count_Reset;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}
Stimulus CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1 {
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_B_AVAILABLE {
/* A status is always invalid on entry. */
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_A_FREE {
Action Send_RemoteUserFree;
Action Set_Raw_A_Status_Free;
//Action Promote_Raw_A_Status;
//Action Pass_Up_A_Status;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
/* Start T_CCBS3 */
Action Start_T_RECALL;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Test = Get_Raw_A_Status;
Test != Invalid {
/* Only received User A is busy. */
Action Raw_Status_Count_Reset;
Action Send_CCBSBFree;
Action Promote_Raw_A_Status;
Action Pass_Up_A_Status;
/* Optimization due to flattening */
//Test = Get_T_CCBS1_Status;
//Test != Active
{
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
Next_State CC_STATE_SUSPENDED;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
//Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Stop_Extended_T_CCBS1;
Action Start_Extended_T_CCBS1;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_A_FREE {
Action Set_Raw_A_Status_Free;
Action Promote_Raw_A_Status;
Action Pass_Up_A_Status;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_A_BUSY {
Action Add_Raw_A_Status_Busy;
Test = Get_Extended_T_CCBS1_Status;
Test == Active {
Action Pass_Up_Status_Rsp_A;
}
}
Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
Test = Get_Raw_A_Status;
Test != Invalid {
/* Only received User A is busy. */
Action Raw_Status_Count_Reset;
}
Test == Invalid {
/* Did not get any responses. */
Action Raw_Status_Count_Increment;
Test = Get_Raw_Status_Count;
Test >= RAW_STATUS_COUNT_MAX {
/* User A no longer present. */
Action Send_CCBSErase(Normal_Unspecified);
Action Pass_Up_CC_Cancel;
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
Action Reset_Raw_A_Status;
Action Send_CCBSStatusRequest;
Action Start_T_CCBS1;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_CCBS1;
Action Stop_Extended_T_CCBS1;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_TIMEOUT_T_RECALL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS3_TIMEOUT);
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_STOP_ALERTING {
/*
* If an earlier link can send us this event then we
* really should be configured for globalRecall like
* the earlier link.
*/
Test = Get_Recall_Mode;
Test == globalRecall {
Action Send_CCBSStopAlerting;
}
Action Stop_T_RECALL;
Action Reset_A_Status;
Action Raw_Status_Count_Reset;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
Test = Get_Recall_Mode;
Test == globalRecall {
Action Send_CCBSStopAlerting;
}
Action Stop_T_RECALL;
Next_State CC_STATE_CALLBACK;
}
Stimulus CC_EVENT_A_STATUS {
Action Set_Raw_A_Status_Free;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_CALLBACK {
Stimulus CC_EVENT_RECALL {
Action Send_Error_Recall(ROSE_ERROR_CCBS_AlreadyAccepted);
Action Set_Call_To_Hangup;
}
Stimulus CC_EVENT_A_STATUS {
Action Set_Raw_A_Status_Free;
Action Pass_Up_Status_Rsp_A_Indirect;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(T_CCBS2_TIMEOUT);
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
Action Pass_Up_CC_Cancel;
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CCBSErase(Normal_Unspecified);
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,181 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTMP monitor.
*
* The CCBSStatusRequest messages are handled independently from this FSM.
*
* The CCBSInterrogate/CCNRInterrogate messages are initiated by a dialplan
* application/AMI/CLI (future) and are handled outside of this FSM.
*/
FSM CC_PTMP_Monitor
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
/*
* Before event is posted:
* Received CallInfoRetain
* Created cc_record
* Saved CallLinkageID
*/
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering as a safeguard in case the network cable is disconnected.
* The timer should be set much longer than the network T_RETENTION
* timer so normally the CC records will be cleaned up by network
* activity.
*/
Stimulus CC_EVENT_CC_REQUEST {
/* cc_record->is_ccnr is set before event posted. */
Action Queue_CC_Request;
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
/*
* Received EraseCallLinkageID
* T_RETENTION expired on the network side so we will pretend
* that it expired on our side.
*/
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Before event is posted:
* Received CCBSRequest/CCNRRequest response
* Saved CCBSReference
*/
Action Relese_LinkID;
Action Pass_Up_CC_Req_Rsp_Success;
Action Stop_T_ACTIVATE;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_WAIT_DESTRUCTION;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/* We were in the middle of a cc-request when we were asked to cancel. */
Epilog {
Action Stop_T_ACTIVATE;
}
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Before event is posted:
* Received CCBSRequest/CCNRRequest response
* Saved CCBSReference
*/
Action Send_CC_Deactivate_Req;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_B_FREE {
/* Received CCBSBFree */
Action Pass_Up_B_Free;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received CCBSRemoteUserFree */
Action Pass_Up_Remote_User_Free;
Next_State CC_STATE_WAIT_CALLBACK;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_STOP_ALERTING {
Action Pass_Up_Stop_Alerting;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
Next_State CC_STATE_CALLBACK;
}
}
State CC_STATE_CALLBACK {
/*
* We are waiting for the CC records to be torn down because
* CC is complete.
* This state is mainly to block CC_EVENT_STOP_ALERTING since
* we are the one doing the CC recall so we do not need to stop
* alerting.
*/
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_CALLBACK) {
Prolog {
/*
* Start T_CCBS2 or T_CCNR2 depending upon CC mode.
* For PTMP TE mode these timers are not defined. However,
* we will use them anyway to protect our resources from leaks
* caused by the network cable being disconnected. These
* timers should be set much longer than the network
* so normally the CC records will be cleaned up by network
* activity.
*/
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Send_CC_Deactivate_Req;
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Deactivate_Req;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,225 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTMP monitor.
*
* The CCBSStatusRequest messages are handled independently from this FSM.
*
* The CCBSInterrogate/CCNRInterrogate messages are initiated by a dialplan
* application/AMI/CLI (future) and are handled outside of this FSM.
*/
FSM CC_PTMP_Monitor
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
/*
* Before event is posted:
* Received CallInfoRetain
* Created cc_record
* Saved CallLinkageID
*/
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering as a safeguard in case the network cable is disconnected.
* The timer should be set much longer than the network T_RETENTION
* timer so normally the CC records will be cleaned up by network
* activity.
*/
Stimulus CC_EVENT_CC_REQUEST {
/* cc_record->is_ccnr is set before event posted. */
Action Queue_CC_Request;
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
/*
* Received EraseCallLinkageID
* T_RETENTION expired on the network side so we will pretend
* that it expired on our side.
*/
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Before event is posted:
* Received CCBSRequest/CCNRRequest response
* Saved CCBSReference
*/
Action Relese_LinkID;
Action Pass_Up_CC_Req_Rsp_Success;
Action Stop_T_ACTIVATE;
/*
* Start T_CCBS2 or T_CCNR2 depending upon CC mode.
* For PTMP TE mode these timers are not defined. However,
* we will use them anyway to protect our resources from leaks
* caused by the network cable being disconnected. These
* timers should be set much longer than the network
* so normally the CC records will be cleaned up by network
* activity.
*/
Action Start_T_SUPERVISION;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_WAIT_DESTRUCTION;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/* We were in the middle of a cc-request when we were asked to cancel. */
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Before event is posted:
* Received CCBSRequest/CCNRRequest response
* Saved CCBSReference
*/
Action Send_CC_Deactivate_Req;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_B_FREE {
/* Received CCBSBFree */
Action Pass_Up_B_Free;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received CCBSRemoteUserFree */
Action Pass_Up_Remote_User_Free;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Send_CC_Deactivate_Req;
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Deactivate_Req;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_STOP_ALERTING {
Action Pass_Up_Stop_Alerting;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
Next_State CC_STATE_CALLBACK;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Send_CC_Deactivate_Req;
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Deactivate_Req;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_CALLBACK {
/*
* We are waiting for the CC records to be torn down because
* CC is complete.
* This state is mainly to block CC_EVENT_STOP_ALERTING since
* we are the one doing the CC recall so we do not need to stop
* alerting.
*/
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Send_CC_Deactivate_Req;
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Deactivate_Req;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,152 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTP agent.
*/
FSM CC_PTP_Agent
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_PENDING_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_PENDING_AVAILABLE {
Stimulus CC_EVENT_MSG_ALERTING {
Action Send_CC_Available(Q931_ALERTING);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_MSG_DISCONNECT {
Action Send_CC_Available(Q931_DISCONNECT);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_AVAILABLE {
/*
* For PTP mode the T_RETENTION timer is not defined. However,
* we will use it anyway in this state to protect our resources
* from leaks caused by user A not requesting CC. This timer
* should be set much longer than the PTMP network link to
* allow for variations in user A's CC offer timer.
*/
Epilog {
Action Stop_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
Action Stop_T_RETENTION;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Prolog {
Action Reset_A_Status;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
Action Pass_Up_A_Status_Indirect;
Test = Get_A_Status;
Test == Busy {
Next_State CC_STATE_SUSPENDED;
}
Action Send_RemoteUserFree;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
/* Received CCBS_T_Suspend */
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
/* Received CCBS_T_Resume */
Action Reset_A_Status;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
/* Received CCBS_T_Suspend */
Action Set_A_Status_Busy;
Action Pass_Up_A_Status;
Next_State CC_STATE_SUSPENDED;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
/* Received CCBS_T_Resume */
Action Set_A_Status_Free;
Action Pass_Up_A_Status;
Next_State CC_STATE_ACTIVATED;
}
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_SUSPENDED) {
Prolog {
/* Start T_CCBS5/T_CCNR5 depending upon CC mode. */
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_RECALL {
/* Received CCBS_T_Call */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,200 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTP agent.
*/
FSM CC_PTP_Agent
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_PENDING_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_PENDING_AVAILABLE {
Stimulus CC_EVENT_MSG_ALERTING {
Action Send_CC_Available(Q931_ALERTING);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_MSG_DISCONNECT {
Action Send_CC_Available(Q931_DISCONNECT);
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_AVAILABLE {
/*
* For PTP mode the T_RETENTION timer is not defined. However,
* we will use it anyway in this state to protect our resources
* from leaks caused by user A not requesting CC. This timer
* should be set much longer than the PTMP network link to
* allow for variations in user A's CC offer timer.
*/
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
Action Stop_T_RETENTION;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Pass_Up_CC_Cancel;
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/* Start T_CCBS5/T_CCNR5 depending upon CC mode. */
Action Start_T_SUPERVISION;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_REMOTE_USER_FREE {
Action Pass_Up_A_Status_Indirect;
Test = Get_A_Status;
Test == Busy {
Next_State CC_STATE_SUSPENDED;
}
Action Send_RemoteUserFree;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
/* Received CCBS_T_Suspend */
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
/* Received CCBS_T_Resume */
Action Reset_A_Status;
}
Stimulus CC_EVENT_RECALL {
/* Received CCBS_T_Call */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
/* Received CCBS_T_Suspend */
Action Set_A_Status_Busy;
Action Pass_Up_A_Status;
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_RECALL {
/* Received CCBS_T_Call */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
/* Received CCBS_T_Resume */
Action Set_A_Status_Free;
Action Pass_Up_A_Status;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
/* Received CCBS_T_Call */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,168 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTP monitor.
*/
FSM CC_PTP_Monitor
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
/* Received CCBS-T-Aailable */
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering.
*/
Stimulus CC_EVENT_CC_REQUEST {
/*
* Before event is posted:
* cc_record->is_ccnr is set.
* The signaling connection call record is created.
*/
Action Queue_CC_Request;
/*
* For PTP mode the T_ACTIVATE timer is not defined. However,
* we will use it to protect our resources from leaks caused
* by the network cable being disconnected.
* This timer should be set longer than normal so the
* CC records will normally be cleaned up by network activity.
*/
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Epilog {
Action Stop_T_ACTIVATE;
}
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received CCBS-T-Request/CCNR-T-Request response
* Before event is posted:
* Negotiated CC retention setting saved
*/
Action Pass_Up_CC_Req_Rsp_Success;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
/*
* If this request fail comes in with the RELEASE_COMPLETE
* message then the post action will never get a chance to
* run. It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Prolog {
Action Reset_A_Status;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received CCBS_T_RemoteUserFree */
Action Pass_Up_Remote_User_Free;
Test = Get_A_Status;
Test == Busy {
Next_State CC_STATE_SUSPENDED;
}
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
Action Reset_A_Status;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
Next_State CC_STATE_SUSPENDED;
}
}
State CC_STATE_SUSPENDED {
Prolog {
Action Send_CC_Suspend;
}
Stimulus CC_EVENT_RESUME {
Action Send_CC_Resume;
Next_State CC_STATE_ACTIVATED;
}
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_SUSPENDED) {
Prolog {
/* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,217 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC PTP monitor.
*/
FSM CC_PTP_Monitor
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
/* Received CCBS-T-Aailable */
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering.
*/
Stimulus CC_EVENT_CC_REQUEST {
/*
* Before event is posted:
* cc_record->is_ccnr is set.
* The signaling connection call record is created.
*/
Action Queue_CC_Request;
/*
* For PTP mode the T_ACTIVATE timer is not defined. However,
* we will use it to protect our resources from leaks caused
* by the network cable being disconnected.
* This timer should be set longer than normal so the
* CC records will normally be cleaned up by network activity.
*/
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received CCBS-T-Request/CCNR-T-Request response
* Before event is posted:
* Negotiated CC retention setting saved
*/
Action Pass_Up_CC_Req_Rsp_Success;
Action Stop_T_ACTIVATE;
/* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
Action Start_T_SUPERVISION;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
/*
* If this request fail comes in with the RELEASE_COMPLETE
* message then the post action will never get a chance to
* run. It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
Action Stop_T_ACTIVATE;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received CCBS_T_RemoteUserFree */
Action Pass_Up_Remote_User_Free;
Test = Get_A_Status;
Test == Busy {
Action Send_CC_Suspend;
Next_State CC_STATE_SUSPENDED;
}
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
Action Reset_A_Status;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
Action Send_CC_Suspend;
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
Action Send_CC_Resume;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,140 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC Q.SIG agent.
*/
FSM CC_QSIG_Agent
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* For Q.SIG mode the T_RETENTION timer is not defined. However,
* we will use it anyway in this state to protect our resources
* from leaks caused by user A not requesting CC. This timer
* should be set much longer than the PTMP network link to
* allow for variations in user A's CC offer timer.
*/
Epilog {
Action Stop_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
/* Send Q931_CALL_PROCEEDING message on signaling link. */
Action Send_Call_Proceeding;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Send ccExecPossible in FACILITY or SETUP. */
Action Send_RemoteUserFree;
Next_State CC_STATE_WAIT_CALLBACK;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
/* Received ccSuspend */
Action Set_A_Status_Busy;
Action Pass_Up_A_Status;
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_RECALL {
/* Received ccRingout */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
/* Received ccResume */
Action Set_A_Status_Free;
Action Pass_Up_A_Status;
Next_State CC_STATE_ACTIVATED;
}
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_SUSPENDED) {
Prolog {
/* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,187 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC Q.SIG agent.
*/
FSM CC_QSIG_Agent
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* For Q.SIG mode the T_RETENTION timer is not defined. However,
* we will use it anyway in this state to protect our resources
* from leaks caused by user A not requesting CC. This timer
* should be set much longer than the PTMP network link to
* allow for variations in user A's CC offer timer.
*/
Stimulus CC_EVENT_MSG_RELEASE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_CC_REQUEST {
Action Pass_Up_CC_Request;
/* Send Q931_CALL_PROCEEDING message on signaling link. */
Action Send_Call_Proceeding;
Action Stop_T_RETENTION;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_INTERNAL_CLEARING {
Action Stop_T_RETENTION;
Action Start_T_RETENTION;
}
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
Action Pass_Up_CC_Cancel;
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Stop_T_RETENTION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
Action Start_T_SUPERVISION;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Send ccExecPossible in FACILITY or SETUP. */
Action Send_RemoteUserFree;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_SUSPEND {
/* Received ccSuspend */
Action Set_A_Status_Busy;
Action Pass_Up_A_Status;
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_RECALL {
/* Received ccRingout */
Action Pass_Up_CC_Call;
Action Set_Original_Call_Parameters;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
/* Received ccResume */
Action Set_A_Status_Free;
Action Pass_Up_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,249 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC Q.SIG monitor.
*/
FSM CC_QSIG_Monitor
{
State CC_STATE_IDLE {
Init {
}
Prolog {
Action Set_Selfdestruct;
}
Stimulus CC_EVENT_AVAILABLE {
/*
* LibPRI will determine if CC will be offered based upon
* if it is even possible.
* Essentially:
* 1) The call must not have been redirected in this link's
* setup.
* 2) Received an ALERTING or received a
* DISCONNECT(busy/congestion).
*/
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering.
*/
Stimulus CC_EVENT_CC_REQUEST {
/*
* Before event is posted:
* cc_record->is_ccnr is set.
* The signaling connection call record is created.
*/
Action Queue_CC_Request;
/* Start QSIG_CC_T1. */
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received ccbsRequest/ccnrRequest response
* Before event is posted:
* Negotiated CC retention setting saved
* Negotiated signaling link retention setting saved
*/
Action Stop_T_ACTIVATE;
Test = Get_msgtype;
Test == Q931_RELEASE {
Action Disassociate_Signaling_Link;
Test = Get_Retain_Signaling_Link;
Test == TRUE {
/*
* The far end did not honor the
* signaling link retention requirement.
* ECMA-186 Section 6.5.2.2.1
*/
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
Action Pass_Up_CC_Req_Rsp_Success;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
/*
* If this request fail comes in with the RELEASE message
* then the post action will never get a chance to run.
* It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
Action Stop_T_ACTIVATE;
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_WAIT_DESTRUCTION;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received ccbsRequest/ccnrRequest response
* Before event is posted:
* Negotiated CC retention setting saved
* Negotiated signaling link retention setting saved
*/
Action Stop_T_ACTIVATE;
Test = Get_msgtype;
Test == Q931_RELEASE {
Action Disassociate_Signaling_Link;
}
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
/*
* If this request fail comes in with the RELEASE message
* then the post action will never get a chance to run.
* It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Stop_T_ACTIVATE;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
//Action Stop_T_ACTIVATE;
Action Hangup_Signaling_Link;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Prolog {
Action Reset_A_Status;
}
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received ccExecPossible */
Action Pass_Up_Remote_User_Free;
/*
* ECMA-186 Section 6.5.2.1.7
* Implied switch to retain-signaling-link.
*/
Action Set_Retain_Signaling_Link;
Test = Get_msgtype;
Test == Q931_SETUP {
/* Send Q931_CALL_PROCEEDING message on signaling link. */
Action Send_Call_Proceeding;
}
Test = Get_A_Status;
Test == Busy {
Next_State CC_STATE_SUSPENDED;
}
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
Action Reset_A_Status;
}
}
State CC_STATE_WAIT_CALLBACK {
Prolog {
/* Start QSIG_CC_T3 */
Action Start_T_RECALL;
}
Epilog {
Action Stop_T_RECALL;
}
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
Next_State CC_STATE_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_TIMEOUT_T_RECALL {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_CALLBACK {
}
State CC_STATE_SUSPENDED {
Prolog {
/*
* The ccSuspend will be sent in a FACILITY or CONNECT
* message depending upon the CIS call state.
*/
Action Send_CC_Suspend;
}
Stimulus CC_EVENT_RESUME {
Action Send_CC_Resume;
Next_State CC_STATE_ACTIVATED;
}
}
Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_CALLBACK, CC_STATE_SUSPENDED) {
Prolog {
/* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
Action Start_T_SUPERVISION;
}
Epilog {
Action Stop_T_SUPERVISION;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Next_State CC_STATE_IDLE;
}
}
}

View File

@@ -1,327 +0,0 @@
/*
* FSM pseudo code used in the design/implementation of the CC Q.SIG monitor.
*/
FSM CC_QSIG_Monitor
{
State CC_STATE_IDLE {
Stimulus CC_EVENT_AVAILABLE {
/*
* LibPRI will determine if CC will be offered based upon
* if it is even possible.
* Essentially:
* 1) The call must not have been redirected in this link's
* setup.
* 2) Received an ALERTING or received a
* DISCONNECT(busy/congestion).
*/
Action Pass_Up_CC_Available;
Next_State CC_STATE_AVAILABLE;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
}
}
State CC_STATE_AVAILABLE {
/*
* The upper layer is responsible for canceling the CC available
* offering.
*/
Stimulus CC_EVENT_CC_REQUEST {
/*
* Before event is posted:
* cc_record->is_ccnr is set.
* The signaling connection call record is created.
*/
Action Queue_CC_Request;
/* Start QSIG_CC_T1. */
Action Start_T_ACTIVATE;
Next_State CC_STATE_REQUESTED;
}
Stimulus CC_EVENT_CANCEL {
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_REQUESTED {
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received ccbsRequest/ccnrRequest response
* Before event is posted:
* Negotiated CC retention setting saved
* Negotiated signaling link retention setting saved
*/
Action Stop_T_ACTIVATE;
Test = Get_msgtype;
Test == Q931_RELEASE {
Action Disassociate_Signaling_Link;
Test = Get_Retain_Signaling_Link;
Test == TRUE {
/*
* The far end did not honor the
* signaling link retention requirement.
* ECMA-186 Section 6.5.2.2.1
*/
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
Action Pass_Up_CC_Req_Rsp_Success;
/* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
Action Start_T_SUPERVISION;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
Action Pass_Up_CC_Cancel;
/*
* If this request fail comes in with the RELEASE message
* then the post action will never get a chance to run.
* It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
Action Stop_T_ACTIVATE;
/* Claim it was a timeout */
Action Pass_Up_CC_Req_Rsp_Timeout;
Action Pass_Up_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CANCEL {
Next_State CC_STATE_WAIT_DESTRUCTION;
}
}
State CC_STATE_WAIT_DESTRUCTION {
/*
* Delayed disconnect of the signaling link to allow subcmd events
* from the signaling link to be passed up.
*/
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
* Received ccbsRequest/ccnrRequest response
* Before event is posted:
* Negotiated CC retention setting saved
* Negotiated signaling link retention setting saved
*/
Action Stop_T_ACTIVATE;
Test = Get_msgtype;
Test == Q931_RELEASE {
Action Disassociate_Signaling_Link;
}
Action Send_CC_Cancel;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
/*
* If this request fail comes in with the RELEASE message
* then the post action will never get a chance to run.
* It will be aborted because the CC_EVENT_SIGNALING_GONE
* will be processed first.
*/
Action Post_HANGUP_SIGNALING;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Stop_T_ACTIVATE;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_HANGUP_SIGNALING {
//Action Stop_T_ACTIVATE;
Action Hangup_Signaling_Link;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_ACTIVATED {
Stimulus CC_EVENT_REMOTE_USER_FREE {
/* Received ccExecPossible */
Action Pass_Up_Remote_User_Free;
/*
* ECMA-186 Section 6.5.2.1.7
* Implied switch to retain-signaling-link.
*/
Action Set_Retain_Signaling_Link;
Test = Get_msgtype;
Test == Q931_SETUP {
/* Send Q931_CALL_PROCEEDING message on signaling link. */
Action Send_Call_Proceeding;
}
Test = Get_A_Status;
Test == Busy {
/*
* The ccSuspend will be sent in a FACILITY or CONNECT
* message depending upon the CIS call state.
*/
Action Send_CC_Suspend;
Next_State CC_STATE_SUSPENDED;
}
/* Start QSIG_CC_T3 */
Action Start_T_RECALL;
Next_State CC_STATE_WAIT_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Action Set_A_Status_Busy;
}
Stimulus CC_EVENT_RESUME {
Action Reset_A_Status;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_WAIT_CALLBACK {
Stimulus CC_EVENT_RECALL {
/* The original call parameters have already been set. */
Action Queue_SETUP_Recall;
Action Stop_T_RECALL;
Next_State CC_STATE_CALLBACK;
}
Stimulus CC_EVENT_SUSPEND {
Action Stop_T_RECALL;
/*
* The ccSuspend will be sent in a FACILITY or CONNECT
* message depending upon the CIS call state.
*/
Action Send_CC_Suspend;
Next_State CC_STATE_SUSPENDED;
}
Stimulus CC_EVENT_TIMEOUT_T_RECALL {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_RECALL;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_CALLBACK {
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
State CC_STATE_SUSPENDED {
Stimulus CC_EVENT_RESUME {
Action Send_CC_Resume;
Action Reset_A_Status;
Next_State CC_STATE_ACTIVATED;
}
Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
Action Pass_Up_CC_Cancel;
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_SIGNALING_GONE {
/* Signaling link cleared. */
Action Disassociate_Signaling_Link;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received ccCancel */
Action Pass_Up_CC_Cancel;
Action Post_HANGUP_SIGNALING;
Action Stop_T_SUPERVISION;
Next_State CC_STATE_WAIT_DESTRUCTION;
}
Stimulus CC_EVENT_CANCEL {
Action Send_CC_Cancel;
Action Stop_T_SUPERVISION;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
}
}

2084
libpri.h

File diff suppressed because it is too large Load Diff

113
mkdep Executable file
View File

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

2098
pri.c

File diff suppressed because it is too large Load Diff

1764
pri_aoc.c

File diff suppressed because it is too large Load Diff

7883
pri_cc.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,265 +0,0 @@
/*
This file contains all data structures and definitions associated
with facility message usage and the ROSE components included
within those messages.
by Matthew Fredrickson <creslin@digium.com>
Copyright (C) Digium, Inc. 2004-2005
*/
/*
* 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_FACILITY_H
#define _PRI_FACILITY_H
#include "pri_q931.h"
#include "rose.h"
/* 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
/* Q.952 Divert cause */
#define Q952_DIVERT_REASON_UNKNOWN 0x00
#define Q952_DIVERT_REASON_CFU 0x01
#define Q952_DIVERT_REASON_CFB 0x02
#define Q952_DIVERT_REASON_CFNR 0x03
#define Q952_DIVERT_REASON_CD 0x04
#define Q952_DIVERT_REASON_IMMEDIATE 0x05
/* Q.SIG Divert cause. Listed in ECMA-174 */
#define QSIG_DIVERT_REASON_UNKNOWN 0x00 /* Call forward unknown reason */
#define QSIG_DIVERT_REASON_CFU 0x01 /* Call Forward Unconditional (other reason) */
#define QSIG_DIVERT_REASON_CFB 0x02 /* Call Forward Busy */
#define QSIG_DIVERT_REASON_CFNR 0x03 /* Call Forward No Reply */
/* Q.932 Type of number */
#define Q932_TON_UNKNOWN 0x00
#define Q932_TON_INTERNATIONAL 0x01
#define Q932_TON_NATIONAL 0x02
#define Q932_TON_NET_SPECIFIC 0x03
#define Q932_TON_SUBSCRIBER 0x04
#define Q932_TON_ABBREVIATED 0x06
/* 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
/*! Reasons an APDU callback is called. */
enum APDU_CALLBACK_REASON {
/*!
* \brief Transmit facility ie 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 apdu_msg_data {
/*! Decoded response message contents. */
union {
const struct rose_msg_result *result;
const struct rose_msg_error *error;
const struct rose_msg_reject *reject;
} response;
/*! Q.931 message type the response came in with. */
int type;
};
union apdu_callback_param {
void *ptr;
long value;
char pad[8];
};
/* So calls to pri_call_apdu_find() will not find an aliased event. */
#define APDU_INVALID_INVOKE_ID 0x10000
#define APDU_TIMEOUT_MSGS_ONLY -1
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 APDU_TIMEOUT_MSGS_ONLY to "timeout" with the message_type list only.
*/
int timeout_time;
/*! Number of Q.931 messages the APDU can "timeout" on. */
unsigned num_messages;
/*! Q.931 message list to "timeout" on. */
int message_type[5];
/*!
* \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 struct apdu_msg_data *msg);
/*! \brief Sender data for the callback function to identify the particular APDU. */
union apdu_callback_param user;
};
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];
};
void rose_copy_number_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePartyNumber *rose_number);
void rose_copy_subaddress_to_q931(struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, const struct rosePartySubaddress *rose_subaddress);
void rose_copy_address_to_q931(struct pri *ctrl, struct q931_party_address *q931_address, const struct roseAddress *rose_address);
void rose_copy_address_to_id_q931(struct pri *ctrl, struct q931_party_id *q931_address, const struct roseAddress *rose_address);
void rose_copy_presented_number_screened_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePresentedNumberScreened *rose_presented);
void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePresentedNumberUnscreened *rose_presented);
void rose_copy_presented_address_screened_to_id_q931(struct pri *ctrl, struct q931_party_id *q931_address, const struct rosePresentedAddressScreened *rose_presented);
void rose_copy_name_to_q931(struct pri *ctrl, struct q931_party_name *qsig_name, const struct roseQsigName *rose_name);
void q931_copy_number_to_rose(struct pri *ctrl, struct rosePartyNumber *rose_number, const struct q931_party_number *q931_number);
void q931_copy_subaddress_to_rose(struct pri *ctrl, struct rosePartySubaddress *rose_subaddress, const struct q931_party_subaddress *q931_subaddress);
void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address, const struct q931_party_address *q931_address);
void q931_copy_id_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address, const struct q931_party_id *q931_address);
void q931_copy_presented_number_screened_to_rose(struct pri *ctrl, struct rosePresentedNumberScreened *rose_presented, const struct q931_party_number *q931_number);
void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl, struct rosePresentedNumberUnscreened *rose_presented, const struct q931_party_number *q931_number);
void q931_copy_presented_id_address_screened_to_rose(struct pri *ctrl, struct rosePresentedAddressScreened *rose_presented, const struct q931_party_id *q931_address);
void q931_copy_name_to_rose(struct pri *ctrl, struct roseQsigName *rose_name, const struct q931_party_name *qsig_name);
int rose_error_msg_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id, enum rose_error_code code);
int send_facility_error(struct pri *ctrl, q931_call *call, int invoke_id, enum rose_error_code code);
int rose_result_ok_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id);
int send_facility_result_ok(struct pri *ctrl, q931_call *call, int invoke_id);
/* 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);
/* starts a 2BCT */
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);
/* starts a QSIG Path Replacement */
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int etsi_initiate_transfer(struct pri *ctrl, q931_call *call_1, q931_call *call_2);
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);
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
int rose_request_subaddress_encode(struct pri *ctrl, struct q931_call *call);
int send_subaddress_transfer(struct pri *ctrl, struct q931_call *call);
int rose_diverting_leg_information1_encode(struct pri *pri, q931_call *call);
int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int messagetype);
int rose_connected_name_encode(struct pri *pri, q931_call *call, int messagetype);
int rose_called_name_encode(struct pri *pri, q931_call *call, int messagetype);
int pri_call_apdu_queue(q931_call *call, int messagetype, const unsigned char *apdu, int apdu_len, struct apdu_callback_data *response);
void pri_call_apdu_queue_cleanup(q931_call *call);
struct apdu_event *pri_call_apdu_find(struct q931_call *call, int invoke_id);
int pri_call_apdu_extract(struct q931_call *call, struct apdu_event *extract);
void pri_call_apdu_delete(struct q931_call *call, struct apdu_event *doomed);
/* Adds the "standard" APDUs to a call */
int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
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 pri_cc_interrogate_rsp(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
void pri_cc_qsig_cancel(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
void pri_cc_qsig_exec_possible(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
int aoc_charging_request_send(struct pri *ctrl, q931_call *c, enum PRI_AOC_REQUEST aoc_request_flag);
void aoc_etsi_aoc_request(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_s_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_s_special_arrangement(struct pri *ctrl, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_d_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_d_charging_unit(struct pri *ctrl, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_e_currency(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
#endif /* _PRI_FACILITY_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,25 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, 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.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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_Q921_H
@@ -35,15 +30,15 @@
#include <endian.h>
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __BIG_ENDIAN _BIG_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#endif
/* Timer values */
#define T_WAIT_MIN 2000
#define T_WAIT_MAX 10000
#define T_200 1000 /* 1 second between SABME's */
#define T_203 10000 /* 10 seconds with no packets max */
#define N_200 3 /* 3 retries */
#define Q921_FRAMETYPE_MASK 0x3
@@ -51,14 +46,11 @@
#define Q921_FRAMETYPE_I 0x0
#define Q921_FRAMETYPE_S 0x1
#define Q921_TEI_GROUP 127
#define Q921_TEI_PRI 0
#define Q921_TEI_GROUP 127
#define Q921_TEI_GR303_EOC_PATH 0
#define Q921_TEI_GR303_EOC_OPS 4
#define Q921_TEI_GR303_TMC_SWITCHING 0
#define Q921_TEI_GR303_TMC_SWITCHING 0
#define Q921_TEI_GR303_TMC_CALLPROC 0
#define Q921_TEI_AUTO_FIRST 64
#define Q921_TEI_AUTO_LAST 126
#define Q921_SAPI_CALL_CTRL 0
#define Q921_SAPI_GR303_EOC 1
@@ -71,17 +63,6 @@
#define Q921_SAPI_LAYER2_MANAGEMENT 63
/*! Q.921 TEI management message type */
enum q921_tei_identity {
Q921_TEI_IDENTITY_REQUEST = 1,
Q921_TEI_IDENTITY_ASSIGNED = 2,
Q921_TEI_IDENTITY_DENIED = 3,
Q921_TEI_IDENTITY_CHECK_REQUEST = 4,
Q921_TEI_IDENTITY_CHECK_RESPONSE = 5,
Q921_TEI_IDENTITY_REMOVE = 6,
Q921_TEI_IDENTITY_VERIFY = 7,
};
typedef struct q921_header {
#if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t sapi:6; /* Service Access Point Indentifier (always 0 for PRI) (0) */
@@ -97,7 +78,7 @@ typedef struct q921_header {
u_int8_t tei:7; /* Terminal Endpoint Identifier (0) */
#endif
u_int8_t data[0]; /* Further data */
} __attribute__ ((packed)) q921_header;
} q921_header;
/* A Supervisory Format frame */
typedef struct q921_s {
@@ -117,7 +98,7 @@ typedef struct q921_s {
#endif
u_int8_t data[0]; /* Any further data */
u_int8_t fcs[2]; /* At least an FCS */
} __attribute__ ((packed)) q921_s;
} q921_s;
/* An Unnumbered Format frame */
typedef struct q921_u {
@@ -135,7 +116,7 @@ typedef struct q921_u {
#endif
u_int8_t data[0]; /* Any further data */
u_int8_t fcs[2]; /* At least an FCS */
} __attribute__ ((packed)) q921_u;
} q921_u;
/* An Information frame */
typedef struct q921_i {
@@ -163,132 +144,32 @@ typedef union {
struct q921_header h;
} q921_h;
enum q921_tx_frame_status {
Q921_TX_FRAME_NEVER_SENT,
Q921_TX_FRAME_PUSHED_BACK,
Q921_TX_FRAME_SENT,
};
typedef struct q921_frame {
struct q921_frame *next; /*!< Next in list */
int len; /*!< Length of header + body */
enum q921_tx_frame_status status; /*!< Tx frame status */
q921_i h; /*!< Actual frame contents. */
struct q921_frame *next; /* Next in list */
int len; /* Length of header + body */
int transmitted; /* Have we been transmitted */
q921_i h;
} q921_frame;
#define Q921_INC(j) (j) = (((j) + 1) % 128)
#define Q921_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_LINK_CONNECTION_RELEASED, /* Also known as TEI_ASSIGNED */
Q921_LINK_CONNECTION_ESTABLISHED,
Q921_AWAITING_ESTABLISH,
Q921_AWAITING_RELEASE
} q921_state;
/*! TEI identity check procedure states. */
enum q921_tei_check_state {
/*! Not participating in the TEI check procedure. */
Q921_TEI_CHECK_NONE,
/*! No reply to TEI check received. */
Q921_TEI_CHECK_DEAD,
/*! Reply to TEI check received in current poll. */
Q921_TEI_CHECK_REPLY,
/*! No reply to current TEI check poll received. A previous poll got a reply. */
Q921_TEI_CHECK_DEAD_REPLY,
};
/*! \brief Q.921 link controller structure */
struct q921_link {
/*! Next Q.921 link in the chain. */
struct q921_link *next;
/*! D channel controller associated with this link. */
struct pri *ctrl;
/*!
* \brief Q.931 Dummy call reference call associated with this TEI.
*
* \note If present then this call is allocated with the D
* channel control structure or the link control structure
* unless this is the TE PTMP broadcast TEI or a GR303 link.
*/
struct q931_call *dummy_call;
/*! Q.921 Re-transmission queue */
struct q921_frame *tx_queue;
/*! Q.921 State */
enum q921_state state;
/*! TEI identity check procedure state. */
enum q921_tei_check_state tei_check;
/*! Service Access Profile Identifier (SAPI) of this link */
int sapi;
/*! Terminal Endpoint Identifier (TEI) of this link */
int tei;
/*! TEI assignment random indicator. */
int ri;
/*! V(A) - Next I-frame sequence number needing ack */
int v_a;
/*! V(S) - Next I-frame sequence number to send */
int v_s;
/*! V(R) - Next I-frame sequence number expected to receive */
int v_r;
/* Various timers */
/*! T-200 retransmission timer */
int t200_timer;
/*! Retry Count (T200) */
int RC;
int t202_timer;
int n202_counter;
/*! Max idle time */
int t203_timer;
/*! Layer 2 persistence restart delay timer */
int restart_timer;
/* MDL variables */
int mdl_timer;
int mdl_error;
unsigned int mdl_free_me:1;
unsigned int peer_rx_busy:1;
unsigned int own_rx_busy:1;
unsigned int acknowledge_pending:1;
unsigned int reject_exception:1;
unsigned int l3_initiated:1;
};
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 debugflags, int txrx);
extern void q921_dump(q921_h *h, int len, int showraw, int txrx);
/* Bring up the D-channel */
void q921_start(struct q921_link *link);
void q921_bring_layer2_up(struct pri *ctrl);
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);
int q921_transmit_iframe(struct q921_link *link, void *buf, int len, int cr);
int q921_transmit_uiframe(struct q921_link *link, 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

@@ -1,35 +1,68 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, 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.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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_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,14 +74,14 @@ 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 */
} __attribute__ ((packed)) q931_h;
u_int8_t crv[3];
} q931_h;
/* Message type header */
@@ -61,30 +94,23 @@ typedef struct q931_mh {
u_int8_t f:1;
#endif
u_int8_t data[0];
} __attribute__ ((packed)) q931_mh;
} q931_mh;
/* Information element format */
typedef struct q931_ie {
u_int8_t ie;
u_int8_t len;
u_int8_t data[0];
} __attribute__ ((packed)) q931_ie;
} q931_ie;
#define Q931_RES_HAVEEVENT (1 << 0)
#define Q931_RES_INERRROR (1 << 1)
#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 */
/*! Send this facility APDU on the next message to go out. */
#define Q931_ANY_MESSAGE -1
/* Call Establishment Messages */
#define Q931_ALERTING 0x01
#define Q931_CALL_PROCEEDING 0x02
@@ -109,7 +135,6 @@ typedef struct q931_ie {
#define Q931_CONGESTION_CONTROL 0x79
#define Q931_INFORMATION 0x7b
#define Q931_FACILITY 0x62
#define Q931_REGISTER 0x64 /* Q.932 */
#define Q931_NOTIFY 0x6e
/* Call Management Messages */
@@ -127,27 +152,21 @@ 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 NATIONAL_SERVICE 0x0f
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x07
#define SERVICE_CHANGE_STATUS_INSERVICE 0
#define SERVICE_CHANGE_STATUS_LOOPBACK 1 /* not supported */
#define SERVICE_CHANGE_STATUS_OUTOFSERVICE 2
#define SERVICE_CHANGE_STATUS_REQCONTINUITYCHECK 3 /* not supported */
#define SERVICE_CHANGE_STATUS_SHUTDOWN 4 /* not supported */
/* Special codeset 0 IE */
#define NATIONAL_CHANGE_STATUS 0x1
/* Q.931 / National ISDN Information Elements */
#define Q931_LOCKING_SHIFT 0x90
#define Q931_NON_LOCKING_SHIFT 0x98
#define Q931_BEARER_CAPABILITY 0x04
#define Q931_CAUSE 0x08
#define Q931_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
@@ -176,9 +195,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
@@ -190,7 +208,6 @@ typedef struct q931_ie {
#define Q931_IE_INFO_REQUEST 0x32
#define Q931_IE_SIGNAL 0x34
#define Q931_IE_SWITCHHOOK 0x36
#define Q931_IE_GENERIC_DIGITS (0x37 | Q931_CODESET(6))
#define Q931_IE_FEATURE_ACTIVATE 0x38
#define Q931_IE_FEATURE_IND 0x39
#define Q931_IE_ORIGINAL_CALLED_NUMBER 0x73
@@ -201,278 +218,45 @@ 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,
/*! Master call is aborting. */
Q931_RANKED_CALL_STATE_ABORT,
};
/* EuroISDN */
#define Q931_SENDING_COMPLETE 0xa1
extern int maintenance_service(struct pri *pri, int span, int channel, int changestatus);
/* Q.SIG specific */
#define QSIG_IE_TRANSIT_COUNT 0x31
int q931_receive(struct q921_link *link, 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);
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn, int inband);
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
extern int q931_information(struct pri *pri, q931_call *call, char digit);
extern int q931_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
int q931_connect_acknowledge(struct pri *ctrl, q931_call *call, int channel);
extern int q931_release(struct pri *pri, q931_call *call, int cause);
@@ -482,38 +266,15 @@ extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
extern int q931_restart(struct pri *pri, int channel);
extern int q931_facility(struct pri *pri, q931_call *call);
extern int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode);
extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
struct q931_call *q931_new_call(struct pri *ctrl);
extern q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
extern void q931_dump(q931_h *h, int len, int txrx);
int q931_register(struct pri *ctrl, q931_call *call);
void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
void q931_destroycall(struct pri *pri, q931_call *c);
enum Q931_DL_EVENT {
Q931_DL_EVENT_NONE,
Q931_DL_EVENT_DL_ESTABLISH_IND,
Q931_DL_EVENT_DL_ESTABLISH_CONFIRM,
Q931_DL_EVENT_DL_RELEASE_IND,
Q931_DL_EVENT_DL_RELEASE_CONFIRM,
Q931_DL_EVENT_TEI_REMOVAL,
};
void q931_dl_event(struct q921_link *link, enum Q931_DL_EVENT 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);
extern void __q931_destroycall(struct pri *pri, q931_call *c);
#endif

View File

@@ -1,30 +1,25 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001-2005, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, 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.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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.
*/
/*
@@ -42,7 +37,11 @@
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <dahdi/user.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"
@@ -50,37 +49,37 @@
static int pri_open(char *dev)
{
int dfd;
struct dahdi_params p;
struct zt_params p;
dfd = open(dev, O_RDWR);
if (dfd < 0) {
fprintf(stderr, "Failed to open dchannel '%s': %s\n", dev, strerror(errno));
return -1;
}
if (ioctl(dfd, DAHDI_GET_PARAMS, &p)) {
if (ioctl(dfd, ZT_GET_PARAMS, &p)) {
fprintf(stderr, "Unable to get parameters on '%s': %s\n", dev, strerror(errno));
return -1;
}
if ((p.sigtype != DAHDI_SIG_HDLCRAW) && (p.sigtype != DAHDI_SIG_HDLCFCS)) {
if ((p.sigtype != ZT_SIG_HDLCRAW) && (p.sigtype != ZT_SIG_HDLCFCS)) {
fprintf(stderr, "%s is in %d signalling, not FCS HDLC or RAW HDLC mode\n", dev, p.sigtype);
return -1;
}
return dfd;
}
static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
static void dump_packet(char *buf, int len, int txrx)
{
q921_h *h = (q921_h *)buf;
q921_dump(pri, h, len, PRI_DEBUG_ALL, txrx);
q921_dump(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((q931_h *)(h->i.data), len - 4, txrx);
}
fflush(stdout);
fflush(stderr);
}
static void pri_bridge(int d1, int d2)
static int pri_bridge(int d1, int d2)
{
char buf[1024];
fd_set fds;
@@ -94,8 +93,8 @@ static void pri_bridge(int d1, int d2)
max = d1;
if (max < d2)
max = d2;
ioctl(d1, DAHDI_GETEVENT, &e);
ioctl(d2, DAHDI_GETEVENT, &e);
ioctl(d1, ZT_GETEVENT, &e);
ioctl(d2, ZT_GETEVENT, &e);
res = select(max + 1, &fds, NULL, NULL, NULL);
if (res < 0) {
fprintf(stderr, "Select returned %d: %s\n", res, strerror(errno));
@@ -104,28 +103,18 @@ static void pri_bridge(int d1, int d2)
if (FD_ISSET(d1, &fds)) {
/* Copy from d1 to d2 */
res = read(d1, buf, sizeof(buf));
dump_packet((struct pri *)NULL, buf, res, 1);
dump_packet(buf, res, 1);
res = write(d2, buf, res);
}
if (FD_ISSET(d2, &fds)) {
/* Copy from d2 to d1 */
res = read(d2, buf, sizeof(buf));
dump_packet((struct pri *)NULL, buf, res, 0);
dump_packet(buf, res, 0);
res = write(d1, buf, res);
}
}
}
static void my_pri_message(struct pri *pri, char *stuff)
{
fprintf(stdout, "%s", stuff);
}
static void my_pri_error(struct pri *pri, char *stuff)
{
fprintf(stderr, "%s", stuff);
}
int main(int argc, char *argv[])
{
int d1, d2;
@@ -135,9 +124,6 @@ int main(int argc, char *argv[])
exit(1);
}
pri_set_message(my_pri_message);
pri_set_error(my_pri_error);
d1 = pri_open(argv[1]);
if (d1 < 0)
exit(1);

View File

@@ -1,152 +1,48 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001-2005, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, 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.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libpri.h"
#include "pri_internal.h"
#include <stdio.h>
/*! Initial number of scheduled timer slots. */
#define SCHED_EVENTS_INITIAL 128
/*!
* \brief Maximum number of scheduled timer slots.
* \note Should be a power of 2 and at least SCHED_EVENTS_INITIAL.
*/
#define SCHED_EVENTS_MAX 8192
/*! \brief The maximum number of timers that were active at once. */
static unsigned maxsched = 0;
/*! Last pool id */
static unsigned pool_id = 0;
static int maxsched = 0;
/* Scheduler routines */
/*!
* \internal
* \brief Increase the number of scheduler timer slots available.
*
* \param ctrl D channel controller.
*
* \retval 0 on success.
* \retval -1 on error.
*/
static int pri_schedule_grow(struct pri *ctrl)
int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data)
{
unsigned num_slots;
struct pri_sched *timers;
/* Determine how many slots in the new timer table. */
if (ctrl->sched.num_slots) {
if (SCHED_EVENTS_MAX <= ctrl->sched.num_slots) {
/* Cannot grow the timer table any more. */
return -1;
}
num_slots = ctrl->sched.num_slots * 2;
if (SCHED_EVENTS_MAX < num_slots) {
num_slots = SCHED_EVENTS_MAX;
}
} else {
num_slots = SCHED_EVENTS_INITIAL;
}
/* Get and initialize the new timer table. */
timers = calloc(num_slots, sizeof(struct pri_sched));
if (!timers) {
/* Could not get a new timer table. */
int x;
struct timeval tv;
for (x=1;x<MAX_SCHED;x++)
if (!pri->pri_sched[x].callback)
break;
if (x == MAX_SCHED) {
pri_error("No more room in scheduler\n");
return -1;
}
if (ctrl->sched.timer) {
/* Copy over the old timer table. */
memcpy(timers, ctrl->sched.timer,
ctrl->sched.num_slots * sizeof(struct pri_sched));
free(ctrl->sched.timer);
} else {
/* Creating the timer pool. */
pool_id += SCHED_EVENTS_MAX;
if (pool_id < SCHED_EVENTS_MAX
|| pool_id + (SCHED_EVENTS_MAX - 1) < SCHED_EVENTS_MAX) {
/*
* Not likely to happen.
*
* Timer id's may be aliased if this D channel is used in an
* NFAS group with redundant D channels. Another D channel in
* the group may have the same pool_id.
*/
pri_error(ctrl,
"Pool_id wrapped. Please ignore if you are not using NFAS with backup D channels.\n");
pool_id = SCHED_EVENTS_MAX;
}
ctrl->sched.first_id = pool_id;
}
/* Put the new timer table in place. */
ctrl->sched.timer = timers;
ctrl->sched.num_slots = num_slots;
return 0;
}
/*!
* \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.
*/
unsigned pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data)
{
unsigned max_used;
unsigned x;
struct timeval tv;
max_used = ctrl->sched.max_used;
for (x = 0; x < max_used; ++x) {
if (!ctrl->sched.timer[x].callback) {
break;
}
}
if (x == ctrl->sched.num_slots && pri_schedule_grow(ctrl)) {
pri_error(ctrl, "No more room in scheduler\n");
return 0;
}
if (ctrl->sched.max_used <= x) {
ctrl->sched.max_used = x + 1;
}
if (x >= maxsched) {
maxsched = x + 1;
}
if (x > maxsched)
maxsched = x;
gettimeofday(&tv, NULL);
tv.tv_sec += ms / 1000;
tv.tv_usec += (ms % 1000) * 1000;
@@ -154,169 +50,69 @@ unsigned pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *dat
tv.tv_usec -= 1000000;
tv.tv_sec += 1;
}
ctrl->sched.timer[x].when = tv;
ctrl->sched.timer[x].callback = function;
ctrl->sched.timer[x].data = data;
return ctrl->sched.first_id + x;
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;
unsigned x;
/* Scan the scheduled timer slots backwards so we can update the max_used value. */
for (x = ctrl->sched.max_used; x--;) {
if (ctrl->sched.timer[x].callback) {
if (!closest) {
/* This is the highest sheduled timer slot in use. */
closest = &ctrl->sched.timer[x].when;
ctrl->sched.max_used = x + 1;
} else if ((closest->tv_sec > ctrl->sched.timer[x].when.tv_sec)
|| ((closest->tv_sec == ctrl->sched.timer[x].when.tv_sec)
&& (closest->tv_usec > ctrl->sched.timer[x].when.tv_usec))) {
closest = &ctrl->sched.timer[x].when;
}
}
}
if (!closest) {
/* No scheduled timer slots are active. */
ctrl->sched.max_used = 0;
int x;
/* Check subchannels */
if (pri->subchannel)
closest = pri_schedule_next(pri->subchannel);
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
(!closest || (closest->tv_sec > pri->pri_sched[x].when.tv_sec) ||
((closest->tv_sec == pri->pri_sched[x].when.tv_sec) &&
(closest->tv_usec > pri->pri_sched[x].when.tv_usec))))
closest = &pri->pri_sched[x].when;
}
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)
{
unsigned x;
unsigned max_used;
int x;
void (*callback)(void *);
void *data;
max_used = ctrl->sched.max_used;
for (x = 0; x < max_used; ++x) {
if (ctrl->sched.timer[x].callback
&& ((ctrl->sched.timer[x].when.tv_sec < tv->tv_sec)
|| ((ctrl->sched.timer[x].when.tv_sec == tv->tv_sec)
&& (ctrl->sched.timer[x].when.tv_usec <= tv->tv_usec)))) {
/* This timer has expired. */
ctrl->schedev = 0;
callback = ctrl->sched.timer[x].callback;
data = ctrl->sched.timer[x].data;
ctrl->sched.timer[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.
*
* \return Nothing
*/
void pri_schedule_del(struct pri *ctrl, unsigned id)
void pri_schedule_del(struct pri *pri,int id)
{
struct pri *nfas;
if (!id) {
/* Disabled/unscheduled event id. */
return;
}
if (ctrl->sched.first_id <= id
&& id <= ctrl->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
ctrl->sched.timer[id - ctrl->sched.first_id].callback = NULL;
return;
}
if (ctrl->nfas) {
/* Try to find the timer on another D channel. */
for (nfas = PRI_NFAS_MASTER(ctrl); nfas; nfas = nfas->slave) {
if (nfas->sched.first_id <= id
&& id <= nfas->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
nfas->sched.timer[id - nfas->sched.first_id].callback = NULL;
return;
}
}
}
pri_error(ctrl,
"Asked to delete sched id 0x%08x??? first_id=0x%08x, num_slots=0x%08x\n", id,
ctrl->sched.first_id, ctrl->sched.num_slots);
}
/*!
* \brief Is the scheduled event this callback.
*
* \param ctrl D channel controller.
* \param id Scheduled event id to check.
* 0 is a disabled/unscheduled event id.
* \param function Callback function to call when timeout.
* \param data Value to give callback function when timeout.
*
* \return TRUE if scheduled event has the callback.
*/
int pri_schedule_check(struct pri *ctrl, unsigned id, void (*function)(void *data), void *data)
{
struct pri *nfas;
if (!id) {
/* Disabled/unscheduled event id. */
return 0;
}
if (ctrl->sched.first_id <= id
&& id <= ctrl->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
return ctrl->sched.timer[id - ctrl->sched.first_id].callback == function
&& ctrl->sched.timer[id - ctrl->sched.first_id].data == data;
}
if (ctrl->nfas) {
/* Try to find the timer on another D channel. */
for (nfas = PRI_NFAS_MASTER(ctrl); nfas; nfas = nfas->slave) {
if (nfas->sched.first_id <= id
&& id <= nfas->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
return nfas->sched.timer[id - nfas->sched.first_id].callback == function
&& nfas->sched.timer[id - nfas->sched.first_id].data == data;
}
}
}
pri_error(ctrl,
"Asked to check sched id 0x%08x??? first_id=0x%08x, num_slots=0x%08x\n", id,
ctrl->sched.first_id, ctrl->sched.num_slots);
return 0;
if ((id >= MAX_SCHED) || (id < 0))
pri_error("Asked to delete sched id %d???\n", id);
pri->pri_sched[id].callback = NULL;
}

127
pritest.c
View File

@@ -1,34 +1,29 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001-2005, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* 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.
*/
/*
* This program tests libpri call reception using a dahdi interface.
* This program tests libpri call reception using a zaptel interface.
* Its state machines are setup for RECEIVING CALLS ONLY, so if you
* are trying to both place and receive calls you have to a bit more.
*/
@@ -37,7 +32,6 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
@@ -46,8 +40,12 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include "libpri.h"
#define PRI_DEF_NODETYPE PRI_CPE
@@ -56,23 +54,13 @@
#define MAX_CHAN 32
#define DCHANNEL_TIMESLOT 16
#define READ_SIZE 160
static int offset = 0;
static void do_channel(int fd)
static void do_channel(ZAP *z)
{
/* This is the part that runs on a given channel */
char buf[READ_SIZE];
int res;
int i=0;
while ((res = read(fd, buf, READ_SIZE)) > 0 && (i++ < 1000)) {
if (write(fd, buf, res) == -1) {
fprintf(stderr, "--!! Failed write: %d\n", errno);
break;
}
}
zap_playf(z, "raw.ulaw", 0);
}
struct pri_chan {
@@ -152,57 +140,10 @@ static void hangup_channel(int channo)
chans[channo].needhangup = 0;
}
static int dahdi_open(char *fn)
{
int fd;
int isnum;
int chan = 0;
int bs;
int x;
fprintf(stderr, "dahdi open %s\n", fn);
isnum = 1;
for (x = 0; x < strlen(fn); x++) {
if (!isdigit(fn[x])) {
isnum = 0;
break;
}
}
if (isnum) {
chan = atoi(fn);
if (chan < 1) {
printf("Invalid channel number '%s'\n", fn);
exit(1);
}
fn = "/dev/dahdi/channel";
}
fd = open(fn, O_RDWR /* | O_NONBLOCK */);
if (fd < 0) {
printf("Unable to open '%s': %s\n", fn, strerror(errno));
exit(1);
}
if (chan) {
if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
x = errno;
close(fd);
errno = x;
printf("Unable to specify channel %d: %s\n", chan, strerror(errno));
exit(1);
}
}
bs = READ_SIZE;
if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
printf("Unable to set blocksize '%d': %s\n", bs, strerror(errno));
exit(1);
}
return fd;
}
static void launch_channel(int channo)
{
pid_t pid;
int z;
ZAP *z;
char ch[80];
/* Make sure hangup state is reset */
@@ -219,7 +160,7 @@ static void launch_channel(int channo)
chans[channo].pid = pid;
} else {
sprintf(ch, "%d", channo + offset);
z = dahdi_open(ch);
z = zap_open(ch, 0);
if (z) {
do_channel(z);
exit(0);
@@ -392,8 +333,8 @@ static int run_pri(int dfd, int swtype, int node)
} else if (res > 0) {
e = pri_check_event(pri);
} else if (errno == ELAST) {
res = ioctl(dfd, DAHDI_GETEVENT, &x);
printf("Got DAHDI event: %d\n", x);
res = ioctl(dfd, ZT_GETEVENT, &x);
printf("Got Zaptel event: %d\n", x);
} else if (errno != EINTR)
fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno));
@@ -401,7 +342,7 @@ static int run_pri(int dfd, int swtype, int node)
handle_pri_event(pri, e);
}
res = ioctl(dfd, DAHDI_GETEVENT, &x);
res = ioctl(dfd, ZT_GETEVENT, &x);
if (!res && x) {
fprintf(stderr, "Got event on PRI interface: %d\n", x);
@@ -423,7 +364,7 @@ int main(int argc, char *argv[])
int dfd;
int swtype = PRI_DEF_SWITCHTYPE;
int node = PRI_DEF_NODETYPE;
struct dahdi_params p;
struct zt_params p;
if (argc < 2) {
fprintf(stderr, "Usage: pritest <dchannel> [swtypetype] [nodetype]\n");
exit(1);
@@ -433,11 +374,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failed to open dchannel '%s': %s\n", argv[1], strerror(errno));
exit(1);
}
if (ioctl(dfd, DAHDI_GET_PARAMS, &p)) {
if (ioctl(dfd, ZT_GET_PARAMS, &p)) {
fprintf(stderr, "Unable to get parameters on '%s': %s\n", argv[1], strerror(errno));
exit(1);
}
if ((p.sigtype != DAHDI_SIG_HDLCRAW) && (p.sigtype != DAHDI_SIG_HDLCFCS)) {
if ((p.sigtype != ZT_SIG_HDLCRAW) && (p.sigtype != ZT_SIG_HDLCFCS)) {
fprintf(stderr, "%s is in %d signalling, not FCS HDLC or RAW HDLC mode\n", argv[1], p.sigtype);
exit(1);
}

3658
q921.c

File diff suppressed because it is too large Load Diff

10141
q931.c

File diff suppressed because it is too large Load Diff

2958
rose.c

File diff suppressed because it is too large Load Diff

4432
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

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,686 +0,0 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Copyright (C) 2010 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 Message Waiting Indication (MWI) operations
*
* Message Waiting Indication (MWI) supplementary service EN 300 745-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 MessageID 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_id
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
static unsigned char *rose_enc_etsi_message_id(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const struct roseEtsiMessageID *msg_id)
{
unsigned char *seq_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, msg_id->reference_number));
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, msg_id->status));
ASN1_CONSTRUCTED_END(seq_len, pos, end);
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_etsi_MWIActivate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
const struct roseEtsiMWIActivate_ARG *mwi_activate;
unsigned char *seq_len;
unsigned char *explicit_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
mwi_activate = &args->etsi.MWIActivate;
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_activate->receiving_user_number));
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
mwi_activate->basic_service));
if (mwi_activate->controlling_user_number.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_activate->controlling_user_number));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_activate->number_of_messages_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
mwi_activate->number_of_messages));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_activate->controlling_user_provided_number.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_activate->controlling_user_provided_number));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_activate->time_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4);
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
mwi_activate->time.str, sizeof(mwi_activate->time.str) - 1));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_activate->message_id_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5);
ASN1_CALL(pos, rose_enc_etsi_message_id(ctrl, pos, end,
&mwi_activate->message_id));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_activate->mode_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 6);
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
mwi_activate->mode));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
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_etsi_MWIDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
const struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
unsigned char *seq_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
mwi_deactivate = &args->etsi.MWIDeactivate;
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_deactivate->receiving_user_number));
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
mwi_deactivate->basic_service));
if (mwi_deactivate->controlling_user_number.length) {
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_deactivate->controlling_user_number));
}
if (mwi_deactivate->mode_present) {
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
mwi_deactivate->mode));
}
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \brief Encode the MWIIndicate 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_MWIIndicate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
const struct roseEtsiMWIIndicate_ARG *mwi_indicate;
unsigned char *seq_len;
unsigned char *explicit_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
mwi_indicate = &args->etsi.MWIIndicate;
if (mwi_indicate->controlling_user_number.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
&mwi_indicate->controlling_user_number));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_indicate->basic_service_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
mwi_indicate->basic_service));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_indicate->number_of_messages_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
mwi_indicate->number_of_messages));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_indicate->controlling_user_provided_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_indicate->controlling_user_provided_number));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_indicate->time_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5);
ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
mwi_indicate->time.str, sizeof(mwi_indicate->time.str) - 1));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
if (mwi_indicate->message_id_present) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 6);
ASN1_CALL(pos, rose_enc_etsi_message_id(ctrl, pos, end,
&mwi_indicate->message_id));
ASN1_CONSTRUCTED_END(explicit_len, pos, end);
}
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \internal
* \brief Decode the MessageID 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_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_etsi_message_id(struct pri *ctrl, const char *name,
unsigned tag, const unsigned char *pos, const unsigned char *end,
struct roseEtsiMessageID *msg_id)
{
int32_t value;
int length;
int seq_offset;
const unsigned char *seq_end;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " %s MessageID %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_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "messageRef", tag, pos, seq_end, &value));
msg_id->reference_number = value;
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, "status", tag, pos, seq_end, &value));
msg_id->status = value;
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
return pos;
}
/*!
* \brief Decode the 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_etsi_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 roseEtsiMWIActivate_ARG *mwi_activate;
mwi_activate = &args->etsi.MWIActivate;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " MWIActivate %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, "receivingUserNr", tag, pos, seq_end,
&mwi_activate->receiving_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->controlling_user_number.length = 0;
mwi_activate->number_of_messages_present = 0;
mwi_activate->controlling_user_provided_number.length = 0;
mwi_activate->time_present = 0;
mwi_activate->message_id_present = 0;
mwi_activate->mode_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) {
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
/* 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, "controllingUserNr", tag, pos,
explicit_end, &mwi_activate->controlling_user_number));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
/* 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_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "numberOfMessages", tag, pos, explicit_end,
&value));
mwi_activate->number_of_messages = value;
mwi_activate->number_of_messages_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
/* 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, "controllingUserProvidedNr", tag,
pos, explicit_end, &mwi_activate->controlling_user_provided_number));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4:
/* 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_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_GENERALIZED_TIME);
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "time", tag, pos, explicit_end,
sizeof(mwi_activate->time.str), mwi_activate->time.str, &str_len));
mwi_activate->time_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5:
/* 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_etsi_message_id(ctrl, "messageId", tag, pos,
explicit_end, &mwi_activate->message_id));
mwi_activate->message_id_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 6:
/* 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_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
ASN1_CALL(pos, asn1_dec_int(ctrl, "mode", tag, pos, explicit_end, &value));
mwi_activate->mode = value;
mwi_activate->mode_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
default:
pos = save_pos;
goto cancel_options;
}
}
cancel_options:;
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
return pos;
}
/*!
* \brief Decode the 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_etsi_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;
struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
mwi_deactivate = &args->etsi.MWIDeactivate;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " MWIDeactivate %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, "receivingUserNr", tag, pos, seq_end,
&mwi_deactivate->receiving_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->controlling_user_number.length = 0;
mwi_deactivate->mode_present = 0;
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
switch (tag) {
default:
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserNr", tag, pos,
seq_end, &mwi_deactivate->controlling_user_number));
break;
case ASN1_TYPE_ENUMERATED:
ASN1_CALL(pos, asn1_dec_int(ctrl, "mode", tag, pos, seq_end, &value));
mwi_deactivate->mode = value;
mwi_deactivate->mode_present = 1;
break;
}
}
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
return pos;
}
/*!
* \brief Decode the MWIIndicate 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_MWIIndicate_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 roseEtsiMWIIndicate_ARG *mwi_indicate;
mwi_indicate = &args->etsi.MWIIndicate;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " MWIIndicate %s\n", asn1_tag2str(tag));
}
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
/*
* A sequence specifies an ordered list of component types.
* However, for simplicity we are not checking the order of
* the remaining optional components.
*/
mwi_indicate->controlling_user_number.length = 0;
mwi_indicate->basic_service_present = 0;
mwi_indicate->number_of_messages_present = 0;
mwi_indicate->controlling_user_provided_number.length = 0;
mwi_indicate->time_present = 0;
mwi_indicate->message_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) {
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
/* 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, "controllingUserNr", tag, pos,
explicit_end, &mwi_indicate->controlling_user_number));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
/* 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_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, explicit_end,
&value));
mwi_indicate->basic_service = value;
mwi_indicate->basic_service_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
/* 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_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "numberOfMessages", tag, pos, explicit_end,
&value));
mwi_indicate->number_of_messages = value;
mwi_indicate->number_of_messages_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4:
/* 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, "controllingUserProvidedNr", tag,
pos, explicit_end, &mwi_indicate->controlling_user_provided_number));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5:
/* 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_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_GENERALIZED_TIME);
ASN1_CALL(pos, asn1_dec_string_max(ctrl, "time", tag, pos, explicit_end,
sizeof(mwi_indicate->time.str), mwi_indicate->time.str, &str_len));
mwi_indicate->time_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 6:
/* 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_etsi_message_id(ctrl, "messageId", tag, pos,
explicit_end, &mwi_indicate->message_id));
mwi_indicate->message_id_present = 1;
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
default:
pos = save_pos;
goto cancel_options;
}
}
cancel_options:;
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
return pos;
}
/* ------------------------------------------------------------------- */
/* end rose_etsi_mwi.c */

View File

@@ -1,682 +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);
/* ETSI Status Request */
unsigned char *rose_enc_etsi_StatusRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_StatusRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_StatusRequest_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_StatusRequest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
/* ETSI Call-Completion Busy Status (CCBS) / Call-Completion No Reply (CCNR) */
unsigned char *rose_enc_etsi_CallInfoRetain_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_EraseCallLinkageID_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSErase_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSRemoteUserFree_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSCall_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSBFree_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSStopAlerting_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSStatusRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSStatusRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_CCBSRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCNRRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_CCNRRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_CCBSInterrogate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCNRInterrogate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBSInterrogate_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_CCNRInterrogate_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_CallInfoRetain_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_EraseCallLinkageID_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_CCBSDeactivate_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_CCBSErase_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_CCBSRemoteUserFree_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_CCBSCall_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_CCBSBFree_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_CCBSStopAlerting_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_CCBSStatusRequest_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_CCBSStatusRequest_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_CCBSRequest_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_CCNRRequest_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_CCBSRequest_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_CCNRRequest_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_CCBSInterrogate_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_CCNRInterrogate_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_CCBSInterrogate_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_CCNRInterrogate_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
/* ETSI CCBS-T/CCNR-T */
unsigned char *rose_enc_etsi_CCBS_T_Request_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCNR_T_Request_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CCBS_T_Request_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_CCNR_T_Request_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_CCBS_T_Request_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_CCNR_T_Request_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_CCBS_T_Request_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_CCNR_T_Request_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
/* ETSI Message Waiting Indication (MWI) */
unsigned char *rose_enc_etsi_MWIActivate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_MWIDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_MWIIndicate_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_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_etsi_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_etsi_MWIIndicate_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_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-CC-Operations */
unsigned char *rose_enc_qsig_CcbsRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcnrRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcbsRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_qsig_CcnrRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enq_qsig_CcCancel_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enq_qsig_CcExecPossible_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcPathReserve_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcPathReserve_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_qsig_CcRingout_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcSuspend_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_qsig_CcResume_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
const unsigned char *rose_dec_qsig_CcbsRequest_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_CcnrRequest_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_CcbsRequest_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_CcnrRequest_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_CcCancel_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_CcExecPossible_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_CcPathReserve_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_CcPathReserve_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_CcRingout_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_CcSuspend_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_CcResume_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,984 +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-CC-Operations (CC)
*
* SS-CC-Operations ECMA-186 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"
/* ------------------------------------------------------------------- */
/*!
* \internal
* \brief Encode the CcExtension 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.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*
* \details
* CcExtension ::= CHOICE {
* none NULL,
* single [14] IMPLICIT Extension,
* multiple [15] IMPLICIT SEQUENCE OF Extension
* }
*/
static unsigned char *rose_enc_qsig_CcExtension(struct pri *ctrl, unsigned char *pos,
unsigned char *end)
{
return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
}
/*!
* \internal
* \brief Encode the CcRequestArg 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 cc_request_arg Call-completion request arguments to encode.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
static unsigned char *rose_enc_qsig_CcRequestArg(struct pri *ctrl, unsigned char *pos,
unsigned char *end, unsigned tag, const struct roseQsigCcRequestArg *cc_request_arg)
{
unsigned char *seq_len;
unsigned char *exp_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
ASN1_CALL(pos, rose_enc_PresentedNumberUnscreened(ctrl, pos, end,
&cc_request_arg->number_a));
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_request_arg->number_b));
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
&cc_request_arg->q931ie));
if (cc_request_arg->subaddr_a.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 10);
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
&cc_request_arg->subaddr_a));
ASN1_CONSTRUCTED_END(exp_len, pos, end);
}
if (cc_request_arg->subaddr_b.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 11);
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
&cc_request_arg->subaddr_b));
ASN1_CONSTRUCTED_END(exp_len, pos, end);
}
if (cc_request_arg->can_retain_service) {
/* Not the DEFAULT value */
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 12,
cc_request_arg->can_retain_service));
}
if (cc_request_arg->retain_sig_connection_present) {
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 13,
cc_request_arg->retain_sig_connection));
}
/* No extension to encode */
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \brief Encode the Q.SIG CcbsRequest 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_CcbsRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcRequestArg(ctrl, pos, end, ASN1_TAG_SEQUENCE,
&args->qsig.CcbsRequest);
}
/*!
* \brief Encode the Q.SIG CcnrRequest 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_CcnrRequest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcRequestArg(ctrl, pos, end, ASN1_TAG_SEQUENCE,
&args->qsig.CcnrRequest);
}
/*!
* \internal
* \brief Encode the CcRequestRes 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 cc_request_res Call-completion request result to encode.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
static unsigned char *rose_enc_qsig_CcRequestRes(struct pri *ctrl, unsigned char *pos,
unsigned char *end, unsigned tag, const struct roseQsigCcRequestRes *cc_request_res)
{
unsigned char *seq_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
if (cc_request_res->no_path_reservation) {
/* Not the DEFAULT value */
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
cc_request_res->no_path_reservation));
}
if (cc_request_res->retain_service) {
/* Not the DEFAULT value */
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
cc_request_res->retain_service));
}
/* No extension to encode */
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \brief Encode the Q.SIG CcbsRequest 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_CcbsRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args)
{
return rose_enc_qsig_CcRequestRes(ctrl, pos, end, ASN1_TAG_SEQUENCE,
&args->qsig.CcbsRequest);
}
/*!
* \brief Encode the Q.SIG CcnrRequest 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_CcnrRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args)
{
return rose_enc_qsig_CcRequestRes(ctrl, pos, end, ASN1_TAG_SEQUENCE,
&args->qsig.CcnrRequest);
}
/*!
* \internal
* \brief Encode the CcOptionalArg 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 cc_optional_arg Call-completion optional arguments to encode.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
static unsigned char *rose_enc_qsig_CcOptionalArg(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const struct roseQsigCcOptionalArg *cc_optional_arg)
{
unsigned char *seq_len;
unsigned char *exp_len;
if (!cc_optional_arg->full_arg_present) {
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_optional_arg->number_a));
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_optional_arg->number_b));
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
&cc_optional_arg->q931ie));
if (cc_optional_arg->subaddr_a.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 10);
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
&cc_optional_arg->subaddr_a));
ASN1_CONSTRUCTED_END(exp_len, pos, end);
}
if (cc_optional_arg->subaddr_b.length) {
/* EXPLICIT tag */
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 11);
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
&cc_optional_arg->subaddr_b));
ASN1_CONSTRUCTED_END(exp_len, pos, end);
}
/* No extension to encode */
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \brief Encode the Q.SIG CcCancel 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_enq_qsig_CcCancel_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcOptionalArg(ctrl, pos, end, &args->qsig.CcCancel);
}
/*!
* \brief Encode the Q.SIG CcExecPossible 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_enq_qsig_CcExecPossible_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcOptionalArg(ctrl, pos, end, &args->qsig.CcExecPossible);
}
/*!
* \brief Encode the Q.SIG CcPathReserve 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_CcPathReserve_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
/*!
* \brief Encode the Q.SIG CcPathReserve 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_CcPathReserve_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args)
{
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
/*!
* \brief Encode the Q.SIG CcRingout 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_CcRingout_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
/*!
* \brief Encode the Q.SIG CcSuspend 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_CcSuspend_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
/*!
* \brief Encode the Q.SIG CcResume 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_CcResume_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_qsig_CcExtension(ctrl, pos, end);
}
/*!
* \internal
* \brief Decode the CcExtension 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.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*
* \details
* CcExtension ::= CHOICE {
* none NULL,
* single [14] IMPLICIT Extension,
* multiple [15] IMPLICIT SEQUENCE OF Extension
* }
*/
static const unsigned char *rose_dec_qsig_CcExtension(struct pri *ctrl, const char *name,
unsigned tag, const unsigned char *pos, const unsigned char *end)
{
int length;
int ext_offset;
const unsigned char *ext_end;
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " %s CcExtension\n", name);
}
switch (tag & ~ASN1_PC_MASK) {
case ASN1_TYPE_NULL:
/* Must not be constructed but we will not check for it for simplicity. */
return asn1_dec_null(ctrl, "none", tag, pos, end);
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
name = "single";
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
name = "multiple";
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(ext_end, ext_offset, length, pos, end);
/* Fixup will skip over the manufacturer extension information */
ASN1_END_FIXUP(ctrl, pos, ext_offset, ext_end, end);
return pos;
}
/*!
* \internal
* \brief Decode the CcRequestArg 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 cc_request_arg 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_CcRequestArg(struct pri *ctrl,
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
struct roseQsigCcRequestArg *cc_request_arg)
{
int32_t value;
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, " %s CcRequestArg %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_PresentedNumberUnscreened(ctrl, "numberA", tag, pos, seq_end,
&cc_request_arg->number_a));
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "numberB", tag, pos, seq_end,
&cc_request_arg->number_b));
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_CLASS_APPLICATION | 0);
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "service", tag, pos, seq_end,
&cc_request_arg->q931ie, sizeof(cc_request_arg->q931ie_contents)));
/*
* A sequence specifies an ordered list of component types.
* However, for simplicity we are not checking the order of
* the remaining optional components.
*/
cc_request_arg->subaddr_a.length = 0;
cc_request_arg->subaddr_b.length = 0;
cc_request_arg->can_retain_service = 0; /* DEFAULT FALSE */
cc_request_arg->retain_sig_connection_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) {
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 10:
/* 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_PartySubaddress(ctrl, "subaddrA", tag, pos,
explicit_end, &cc_request_arg->subaddr_a));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 11:
/* 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_PartySubaddress(ctrl, "subaddrB", tag, pos,
explicit_end, &cc_request_arg->subaddr_b));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 12:
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "can-retain-service", tag, pos,
seq_end, &value));
cc_request_arg->can_retain_service = value;
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 13:
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "retain-sig-connection", tag, pos,
seq_end, &value));
cc_request_arg->retain_sig_connection = value;
cc_request_arg->retain_sig_connection_present = 1;
break;
case ASN1_TYPE_NULL:
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
seq_end));
break;
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 CcbsRequest 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_CcbsRequest_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
return rose_dec_qsig_CcRequestArg(ctrl, "CcbsRequest", tag, pos, end,
&args->qsig.CcbsRequest);
}
/*!
* \brief Decode the Q.SIG CcnrRequest 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_CcnrRequest_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
return rose_dec_qsig_CcRequestArg(ctrl, "CcnrRequest", tag, pos, end,
&args->qsig.CcnrRequest);
}
/*!
* \internal
* \brief Decode the CcRequestRes 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 cc_request_res 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_CcRequestRes(struct pri *ctrl,
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
struct roseQsigCcRequestRes *cc_request_res)
{
int32_t value;
int length;
int seq_offset;
const unsigned char *seq_end;
const unsigned char *save_pos;
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " %s CcRequestRes %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);
/*
* A sequence specifies an ordered list of component types.
* However, for simplicity we are not checking the order of
* the remaining optional components.
*/
cc_request_res->no_path_reservation = 0; /* DEFAULT FALSE */
cc_request_res->retain_service = 0; /* DEFAULT FALSE */
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
save_pos = pos;
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
switch (tag) {
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "no-path-reservation", tag, pos,
seq_end, &value));
cc_request_res->no_path_reservation = value;
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "retain-service", tag, pos, seq_end,
&value));
cc_request_res->retain_service = value;
break;
case ASN1_TYPE_NULL:
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
seq_end));
break;
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 CcbsRequest 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_CcbsRequest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
{
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
return rose_dec_qsig_CcRequestRes(ctrl, "CcbsRequest", tag, pos, end,
&args->qsig.CcbsRequest);
}
/*!
* \brief Decode the Q.SIG CcnrRequest 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_CcnrRequest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
{
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
return rose_dec_qsig_CcRequestRes(ctrl, "CcnrRequest", tag, pos, end,
&args->qsig.CcnrRequest);
}
/*!
* \internal
* \brief Decode the CcOptionalArg 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 cc_optional_arg 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_CcOptionalArg(struct pri *ctrl,
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
struct roseQsigCcOptionalArg *cc_optional_arg)
{
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, " %s CcOptionalArg\n", name);
}
if (tag != (ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0)) {
cc_optional_arg->full_arg_present = 0;
return rose_dec_qsig_CcExtension(ctrl, "extArg", tag, pos, end);
}
cc_optional_arg->full_arg_present = 1;
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " fullArg %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, "numberA", tag, pos, seq_end,
&cc_optional_arg->number_a));
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "numberB", tag, pos, seq_end,
&cc_optional_arg->number_b));
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_CLASS_APPLICATION | 0);
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "service", tag, pos, seq_end,
&cc_optional_arg->q931ie, sizeof(cc_optional_arg->q931ie_contents)));
/*
* A sequence specifies an ordered list of component types.
* However, for simplicity we are not checking the order of
* the remaining optional components.
*/
cc_optional_arg->subaddr_a.length = 0;
cc_optional_arg->subaddr_b.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) {
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 10:
/* 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_PartySubaddress(ctrl, "subaddrA", tag, pos,
explicit_end, &cc_optional_arg->subaddr_a));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 11:
/* 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_PartySubaddress(ctrl, "subaddrB", tag, pos,
explicit_end, &cc_optional_arg->subaddr_b));
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
break;
case ASN1_TYPE_NULL:
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
seq_end));
break;
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 CcCancel 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_CcCancel_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcOptionalArg(ctrl, "CcCancel", tag, pos, end,
&args->qsig.CcCancel);
}
/*!
* \brief Decode the Q.SIG CcExecPossible 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_CcExecPossible_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcOptionalArg(ctrl, "CcExecPossible", tag, pos, end,
&args->qsig.CcCancel);
}
/*!
* \brief Decode the Q.SIG CcPathReserve 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_CcPathReserve_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcExtension(ctrl, "CcPathReserve", tag, pos, end);
}
/*!
* \brief Decode the Q.SIG CcPathReserve 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_CcPathReserve_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
{
return rose_dec_qsig_CcExtension(ctrl, "CcPathReserve", tag, pos, end);
}
/*!
* \brief Decode the Q.SIG CcRingout 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_CcRingout_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcExtension(ctrl, "CcRingout", tag, pos, end);
}
/*!
* \brief Decode the Q.SIG CcSuspend 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_CcSuspend_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcExtension(ctrl, "CcSuspend", tag, pos, end);
}
/*!
* \brief Decode the Q.SIG CcResume 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_CcResume_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_qsig_CcExtension(ctrl, "CcResume", tag, pos, end);
}
/* ------------------------------------------------------------------- */
/* end rose_qsig_cc.c */

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,791 +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.str, sizeof(mwi_activate->timestamp.str) - 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.str, sizeof(record->timestamp.str) - 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.str), mwi_activate->timestamp.str,
&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.str), record->timestamp.str, &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,475 +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, asn1_dec_tag(pos, seq_end, &tag));
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 */

3256
rosetest.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +1,27 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
* Written by Mark Spencer <markster@linux-support.net>
*
* Copyright (C) 2001-2005, Digium, Inc.
* Copyright (C) 2001, Linux Support Services, 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.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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.
*/
/*
* This program tests libpri call reception using a zaptel interface.
* Its state machines are setup for RECEIVING CALLS ONLY, so if you
@@ -48,26 +42,26 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include <pthread.h>
#include <sys/select.h>
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#define DEBUG_LEVEL PRI_DEBUG_ALL
#define PRI_DEF_NODETYPE PRI_CPE
#define PRI_DEF_SWITCHTYPE PRI_SWITCH_NI2
static struct pri *first;
static struct pri *first, *cur;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define TEST_CALLS 1
#define TEST_CALLS 32
static void event1(struct pri *pri, pri_event *e)
{
@@ -84,40 +78,14 @@ static void event1(struct pri *pri, pri_event *e)
sprintf(dest, "60%02d", x + 1);
if (!(calls[x] = pri_new_call(pri))) {
perror("pri_new_call");
continue;
}
#if 0
{
struct pri_sr *sr;
sr = pri_sr_new();
pri_sr_set_channel(sr, x+1, 0, 0);
pri_sr_set_bearer(sr, 0, PRI_LAYER_1_ULAW);
pri_sr_set_called(sr, dest, PRI_NATIONAL_ISDN, 1);
pri_sr_set_caller(sr, num, name, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
pri_sr_set_redirecting(sr, num, PRI_NATIONAL_ISDN, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL);
if (pri_setup(pri, calls[x], sr))
perror("pri_setup");
pri_sr_free(sr);
}
#else
if (pri_call(pri, calls[x], PRI_TRANS_CAP_DIGITAL, x + 1, 1, 1, num,
} else if (pri_call(pri, calls[x], PRI_TRANS_CAP_DIGITAL, x + 1, 1, 1, num,
PRI_NATIONAL_ISDN, name, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
dest, PRI_NATIONAL_ISDN, PRI_LAYER_1_ULAW)) {
perror("pri_call");
}
#endif
}
printf("Setup %d calls!\n", TEST_CALLS);
break;
case PRI_EVENT_RINGING:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
q931_facility(pri, e->ringing.call);
pri_answer(pri, e->ringing.call, e->ringing.channel, 0);
break;
case PRI_EVENT_HANGUP_REQ:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->hangup.call, e->hangup.cause);
break;
default:
printf("PRI 1: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
}
@@ -127,26 +95,13 @@ static void event2(struct pri *pri, pri_event *e)
{
/* CPE */
switch(e->gen.e) {
case PRI_EVENT_RING:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_proceeding(pri, e->ring.call, e->ring.channel, 0);
pri_acknowledge(pri, e->ring.call, e->ring.channel, 0);
break;
case PRI_EVENT_ANSWER:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->answer.call, PRI_CAUSE_NORMAL_UNSPECIFIED);
break;
case PRI_EVENT_HANGUP:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
pri_hangup(pri, e->hangup.call, e->hangup.cause);
break;
case PRI_EVENT_DCHAN_UP:
default:
printf("PRI 2: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
}
}
static void testmsg(struct pri *pri, char *s)
static void testmsg(char *s)
{
char *c;
static int keeplast = 0;
@@ -156,9 +111,9 @@ static void testmsg(struct pri *pri, char *s)
*c = '\0';
c++;
}
if (keeplast || !pri)
if (keeplast)
printf("%s", s);
else if (pri == first)
else if (cur == first)
printf("-1 %s", s);
else
printf("-2 %s", s);
@@ -172,7 +127,7 @@ static void testmsg(struct pri *pri, char *s)
keeplast = 0;
}
static void testerr(struct pri *pri, char *s)
static void testerr(char *s)
{
char *c;
static int keeplast = 0;
@@ -182,9 +137,9 @@ static void testerr(struct pri *pri, char *s)
*c = '\0';
c++;
}
if (keeplast || !pri)
if (keeplast)
printf("%s", s);
else if (pri == first)
else if (cur == first)
printf("=1 %s", s);
else
printf("=2 %s", s);
@@ -204,11 +159,11 @@ static void *dchan(void *data)
/* Joint D-channel */
struct pri *pri = data;
struct timeval *next, tv;
pri_event *e = NULL;
pri_event *e;
fd_set fds;
int res;
for(;;) {
if ((next = pri_schedule_next(pri))) {
if (next == pri_schedule_next(pri)) {
gettimeofday(&tv, NULL);
tv.tv_sec = next->tv_sec - tv.tv_sec;
tv.tv_usec = next->tv_usec - tv.tv_usec;
@@ -225,6 +180,7 @@ static void *dchan(void *data)
FD_SET(pri_fd(pri), &fds);
res = select(pri_fd(pri) + 1, &fds, NULL, NULL, next ? &tv : NULL);
pthread_mutex_lock(&lock);
cur = pri;
if (res < 0) {
perror("select");
} else if (!res) {
@@ -256,23 +212,21 @@ int main(int argc, char *argv[])
perror("socketpair");
exit(1);
}
if (!(pri = pri_new_bri(pair[0], 0, PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
if (!(pri = pri_new(pair[0], PRI_NETWORK, PRI_DEF_SWITCHTYPE))) {
perror("pri(0)");
exit(1);
}
first = pri;
pri_set_debug(pri, DEBUG_LEVEL);
pri_facility_enable(pri);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(0)");
exit(1);
}
if (!(pri = pri_new_bri(pair[1], 0, PRI_CPE, PRI_DEF_SWITCHTYPE))) {
if (!(pri = pri_new(pair[1], PRI_CPE, PRI_DEF_SWITCHTYPE))) {
perror("pri(1)");
exit(1);
}
pri_set_debug(pri, DEBUG_LEVEL);
pri_facility_enable(pri);
if (pthread_create(&tmp, NULL, dchan, pri)) {
perror("thread(1)");
exit(1);