Compare commits

..

2 Commits

Author SHA1 Message Date
Russell Bryant
585c016da8 Importing files for 1.4.11 release.
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.11@1713 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2010-05-20 19:32:32 +00:00
Russell Bryant
f86ab05045 Creating tag for the release of libpri-1.4.11
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.4.11@1712 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2010-05-20 19:31:50 +00:00
43 changed files with 4170 additions and 29104 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

1
.version Normal file
View File

@@ -0,0 +1 @@
1.4.11

1093
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

108
Makefile
View File

@@ -10,25 +10,26 @@
# 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
# Uncomment if you want libpri to count number of Q921/Q931 sent/received
#LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
CC=gcc
GREP=grep
AWK=awk
AR=ar
RANLIB=ranlib
OSARCH=$(shell uname -s)
PROC?=$(shell uname -m)
@@ -46,45 +47,48 @@ STATIC_OBJS= \
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)
copy_string.lo \
pri.lo \
q921.lo \
prisched.lo \
q931.lo \
pri_facility.lo \
asn1_primitive.lo \
rose.lo \
rose_address.lo \
rose_etsi_aoc.lo \
rose_etsi_diversion.lo \
rose_etsi_ect.lo \
rose_other.lo \
rose_q931.lo \
rose_qsig_aoc.lo \
rose_qsig_ct.lo \
rose_qsig_diversion.lo \
rose_qsig_mwi.lo \
rose_qsig_name.lo \
version.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS) $(LIBPRI_OPT)
INSTALL_PREFIX=$(DESTDIR)
INSTALL_BASE=/usr
libdir?=$(INSTALL_BASE)/lib
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
SOFLAGS:=-Wl,-h$(DYNAMIC_LIBRARY)
LDCONFIG = /sbin/ldconfig
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX XGNUX))
LDCONFIG_FLAGS=-n
else
@@ -96,13 +100,11 @@ endif
endif
ifeq (${OSARCH},SunOS)
CFLAGS += -DSOLARIS -I../zaptel-solaris
LDCONFIG =
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 .)
@@ -114,13 +116,7 @@ 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
LIBPRI_OPT = -O2
endif
ifeq ($(CPUARCH),i686)
@@ -128,7 +124,7 @@ CFLAGS += -m32
SOFLAGS += -m32
endif
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY) $(UTILITIES)
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
update:
@if [ -d .svn ]; then \
@@ -154,37 +150,37 @@ 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)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
else
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
install -f $(INSTALL_PREFIX)$(libdir) -m 755 $(DYNAMIC_LIBRARY)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf $(DYNAMIC_LIBRARY) libpri.so)
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
install -f $(INSTALL_PREFIX)$(libdir) -m 644 $(STATIC_LIBRARY)
endif
uninstall:
@echo "Removing Libpri"
rm -f $(INSTALL_PREFIX)$(libdir)/$(STATIC_LIBRARY)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so.$(SONAME)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so
rm -f $(INSTALL_PREFIX)$(libdir)/$(DYNAMIC_LIBRARY)
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.a
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/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 $(CFLAGS)
rosetest: rosetest.o $(STATIC_LIBRARY)
$(CC) -o $@ $< $(STATIC_LIBRARY) $(CFLAGS)
rosetest: rosetest.o
$(CC) -o rosetest rosetest.o -L. -lpri $(CFLAGS)
MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
@@ -195,13 +191,13 @@ MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
$(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)
$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
$(LDCONFIG) $(LDCONFIG_FLAGS) .
ln -sf $(DYNAMIC_LIBRARY) libpri.so
ln -sf libpri.so.$(SONAME) libpri.so
version.c: FORCE
@build_tools/make_version_c > $@.tmp
@@ -209,9 +205,9 @@ version.c: FORCE
@rm -f $@.tmp
clean:
rm -f *.o *.so *.lo
rm -f $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f $(UTILITIES)
rm -f *.o *.so *.lo *.so.$(SONAME)
rm -f testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
rm -f pritest pridump
rm -f .*.d
.PHONY:

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

992
libpri.h

File diff suppressed because it is too large Load Diff

1231
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

@@ -30,7 +30,13 @@
#ifndef _PRI_FACILITY_H
#define _PRI_FACILITY_H
#include "pri_q931.h"
#include "rose.h"
/* Forward declare some structs */
struct fac_extension_header;
struct rose_msg_invoke;
struct rose_msg_result;
struct rose_msg_error;
struct rose_msg_reject;
/* Protocol Profile field */
#define Q932_PROTOCOL_MASK 0x1F
@@ -69,7 +75,7 @@
/*! Reasons an APDU callback is called. */
enum APDU_CALLBACK_REASON {
/*!
* \brief Transmit facility ie setup error. Abort and cleanup.
* \brief Send setup error. Abort and cleanup.
* \note The message may or may not actually get sent.
* \note The callback cannot generate an event subcmd.
* \note The callback should not send messages. Out of order messages will result.
@@ -108,15 +114,10 @@ enum APDU_CALLBACK_REASON {
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_msg_data {
const struct rose_msg_result *result;
const struct rose_msg_error *error;
const struct rose_msg_reject *reject;
};
union apdu_callback_param {
@@ -125,24 +126,15 @@ union apdu_callback_param {
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.
* \note Set to less than 0 for PRI_TIMER_T_RESPONSE time.
*/
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.
*
@@ -157,7 +149,7 @@ struct apdu_callback_data {
*
* \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);
int (*callback)(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const union apdu_msg_data *msg);
/*! \brief Sender data for the callback function to identify the particular APDU. */
union apdu_callback_param user;
};
@@ -181,29 +173,6 @@ struct apdu_event {
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);
@@ -212,17 +181,13 @@ 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);
/* starts a QSIG Path Replacement */
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
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);
@@ -232,8 +197,6 @@ 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 */
@@ -246,20 +209,4 @@ void rose_handle_result(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
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 */

View File

@@ -42,7 +42,6 @@
/* Forward declare some structs */
struct apdu_event;
struct pri_cc_record;
struct pri_sched {
struct timeval when;
@@ -50,19 +49,12 @@ struct pri_sched {
void *data;
};
/*
* libpri needs to be able to allocate B channels to support Q.SIG path reservation.
* Until that happens, path reservation is not possible. Fortunately,
* path reservation is optional with a fallback to what we can implement.
*/
//#define QSIG_PATH_RESERVATION_SUPPORT 1
/*! Maximum number of scheduled events active at the same time. */
#define MAX_SCHED 128
/*! Maximum number of facility ie's to handle per incoming message. */
#define MAX_FACILITY_IES 8
/*! Maximum length of sent display text string. (No null terminator.) */
#define MAX_DISPLAY_TEXT 80
/*! Accumulated pri_message() line until a '\n' is seen on the end. */
struct pri_msg_line {
/*! Accumulated buffer used. */
@@ -79,20 +71,9 @@ struct pri {
void *userdata;
/*! Accumulated pri_message() line. (Valid in master record only) */
struct pri_msg_line *msg_line;
/*! NFAS master/primary channel if appropriate */
struct pri *master;
/*! Next NFAS slaved D channel if appropriate */
struct pri *slave;
struct {
/*! Dynamically allocated array of timers that can grow as needed. */
struct pri_sched *timer;
/*! Numer of timer slots in the allocated array of timers. */
unsigned num_slots;
/*! Maximum timer slots currently needed. */
unsigned max_used;
/*! First timer id in this timer pool. */
unsigned first_id;
} sched;
struct pri *subchannel; /* Sub-channel if appropriate */
struct pri *master; /* Master channel if appropriate */
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */
int debug; /* Debug stuff */
int state; /* State of D-channel */
int switchtype; /* Switch type */
@@ -100,9 +81,9 @@ struct pri {
int localtype; /* Local network type (unknown, network, cpe) */
int remotetype; /* Remote network type (unknown, network, cpe) */
int protodisc; /* Layer 3 protocol discriminator */
unsigned int nfas:1;/* TRUE if this D channel is involved with an NFAS group */
int sapi;
int tei;
int protodisc;
unsigned int bri:1;
unsigned int acceptinbanddisconnect:1; /* Should we allow inband progress after DISCONNECT? */
unsigned int sendfacility:1;
@@ -112,69 +93,69 @@ struct pri {
unsigned int hold_support:1;/* TRUE if upper layer supports call hold. */
unsigned int deflection_support:1;/* TRUE if upper layer supports call deflection/rerouting. */
unsigned int hangup_fix_enabled:1;/* TRUE if should follow Q.931 Section 5.3.2 instead of blindly sending RELEASE_COMPLETE for certain causes */
unsigned int cc_support:1;/* TRUE if upper layer supports call completion. */
unsigned int transfer_support:1;/* TRUE if the upper layer supports ECT */
unsigned int aoc_support:1;/* TRUE if can send AOC events to the upper layer. */
unsigned int manual_connect_ack:1;/* TRUE if the CONNECT_ACKNOWLEDGE is sent with API call */
unsigned int mcid_support:1;/* TRUE if the upper layer supports MCID */
/*! Layer 2 link control for D channel. */
struct q921_link link;
/*! Layer 2 persistence option. */
enum pri_layer2_persistence l2_persistence;
/*! T201 TEI Identity Check timer. */
int t201_timer;
/*! Number of times T201 has expired. */
int t201_expirycnt;
/* MDL variables */
int mdl_error;
int mdl_error_state;
int mdl_timer;
int mdl_free_me;
/* Q.921 State */
int q921_state;
int RC;
int peer_rx_busy:1;
int own_rx_busy:1;
int acknowledge_pending:1;
int reject_exception:1;
int v_s; /* Next N(S) for transmission */
int v_a; /* Last acknowledged frame */
int v_r; /* Next frame expected to be received */
int cref; /* Next call reference value */
int l3initiated;
/* Various timers */
int t203_timer; /* Max idle time */
int t202_timer;
int n202_counter;
int ri;
int t200_timer; /* T-200 retransmission timer */
/* All ISDN Timer values */
int timers[PRI_MAX_TIMERS];
/* Used by scheduler */
struct timeval tv;
int schedev;
pri_event ev; /* Static event thingy */
/*! Subcommands for static event thingy. */
struct pri_subcommands subcmds;
/* Q.921 Re-transmission queue */
struct q921_frame *txqueue;
/* Q.931 calls */
struct q931_call **callpool;
struct q931_call *localpool;
q931_call **callpool;
q931_call *localpool;
/*!
* \brief Q.931 Dummy call reference call associated with this TEI.
* \note If present then this call is allocated as part of the
* D channel control structure.
*/
q931_call *dummy_call;
#ifdef LIBPRI_COUNTERS
/* q921/q931 packet counters */
unsigned int q921_txcount;
unsigned int q921_rxcount;
unsigned int q931_txcount;
unsigned int q931_rxcount;
#endif
short last_invoke; /* Last ROSE invoke ID (Valid in master record only) */
/*! Call completion (Valid in master record only) */
struct {
/*! Active CC records */
struct pri_cc_record *pool;
/*! Last CC record id allocated. */
unsigned short last_record_id;
/*! Last CC PTMP reference id allocated. (0-127) */
unsigned char last_reference_id;
/*! Last CC PTMP linkage id allocated. (0-127) */
unsigned char last_linkage_id;
/*! Configured CC options. */
struct {
/*! PTMP recall mode: globalRecall(0), specificRecall(1) */
unsigned char recall_mode;
/*! Q.SIG Request signaling link retention: release(0), retain(1), do-not-care(2) */
unsigned char signaling_retention_req;
/*! Q.SIG Response request signaling link retention: release(0), retain(1) */
unsigned char signaling_retention_rsp;
#if defined(QSIG_PATH_RESERVATION_SUPPORT)
/*! Q.SIG TRUE if response request can support path reservation. */
unsigned char allow_path_reservation;
#endif /* defined(QSIG_PATH_RESERVATION_SUPPORT) */
} option;
} cc;
/*! For delayed processing of facility ie's. */
struct {
/*! Array of facility ie locations in the current received message. */
@@ -184,15 +165,6 @@ struct pri {
/*! Number of facility ie's in the array from the current received message. */
unsigned char count;
} facility;
/*! Display text policy handling options. */
struct {
/*! Send display text policy option flags. */
unsigned long send;
/*! Receive display text policy option flags. */
unsigned long receive;
} display_flags;
/*! Configured date/time ie send policy option. */
int date_time_send;
};
/*! \brief Maximum name length plus null terminator (From ECMA-164) */
@@ -352,9 +324,12 @@ struct pri_sr {
const char *keypad_digits;
int transferable;
int reversecharge;
int aoc_charging_request;
};
/* Internal switch types */
#define PRI_SWITCH_GR303_EOC_PATH 19
#define PRI_SWITCH_GR303_TMC_SWITCHING 20
#define Q931_MAX_TEI 8
/*! \brief Incoming call transfer states. */
@@ -395,44 +370,11 @@ enum Q931_HOLD_STATE {
Q931_HOLD_STATE_RETRIEVE_IND,
};
/* Only save the first of each BC, HLC, and LLC from the initial SETUP. */
#define CC_SAVED_IE_BC (1 << 0) /*!< BC has already been saved. */
#define CC_SAVED_IE_HLC (1 << 1) /*!< HLC has already been saved. */
#define CC_SAVED_IE_LLC (1 << 2) /*!< LLC has already been saved. */
/*! Saved ie contents for BC, HLC, and LLC. (Only the first of each is saved.) */
struct q931_saved_ie_contents {
/*! Length of saved ie contents. */
unsigned char length;
/*! Saved ie contents data. */
unsigned char data[
/* Bearer Capability has a max length of 12. */
12
/* High Layer Compatibility has a max length of 5. */
+ 5
/* Low Layer Compatibility has a max length of 18. */
+ 18
/* Room for null terminator just in case. */
+ 1];
};
/*! Digested BC parameters. */
struct decoded_bc {
int transcapability;
int transmoderate;
int transmultiple;
int userl1;
int userl2;
int userl3;
int rateadaption;
};
/* q931_call datastructure */
struct q931_call {
struct pri *pri; /* D channel controller (master) */
struct q921_link *link; /* Q.921 link associated with this call. */
struct q931_call *next;
struct pri *pri; /* PRI */
int cr; /* Call Reference */
q931_call *next;
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
int slotmap;
/* An explicit channel (Channel Identifier IE) (-1 means not specified) */
@@ -452,21 +394,20 @@ struct q931_call {
int ri; /* Restart Indicator (Restart Indicator IE) */
/*! Bearer Capability */
struct decoded_bc bc;
/* Bearer Capability */
int transcapability;
int transmoderate;
int transmultiple;
int userl1;
int userl2;
int userl3;
int rateadaption;
/*!
* \brief TRUE if the call is a Call Independent Signalling connection.
* \note The call has no B channel associated with it. (Just signalling)
*/
int cis_call;
/*!
* \brief TRUE if we have recognized a use for this CIS call.
* \note An incoming CIS call will be immediately disconnected if not set.
* This is a safeguard against unhandled incoming CIS calls to protect the
* call reference pool.
*/
int cis_recognized;
/*! \brief TRUE if we will auto disconnect the cis_call we originated. */
int cis_auto_disconnect;
@@ -517,8 +458,6 @@ struct q931_call {
* (Caller-ID for answered or connected-line for originated calls.)
*/
struct q931_party_id remote_id;
/*! \brief Automatic Number Identification (ANI) */
struct q931_party_number ani;
/*!
* \brief Staging place for the Q.931 redirection number ie.
@@ -546,9 +485,9 @@ struct q931_call {
/*! \brief Incoming call transfer state. */
enum INCOMING_CT_STATE incoming_ct_state;
/*! Call hold supplementary state. Valid on master call record only. */
/*! Call hold supplementary state. */
enum Q931_HOLD_STATE hold_state;
/*! Call hold event timer. Valid on master call record only. */
/*! Call hold event timer */
int hold_timer;
int deflection_in_progress; /*!< CallDeflection for NT PTMP in progress. */
@@ -567,13 +506,8 @@ struct q931_call {
int transferable; /* RLT call is transferable */
unsigned int rlt_call_id; /* RLT call id */
/*! ETSI Explicit Call Transfer link id. */
int link_id;
/*! TRUE if link_id is valid. */
int is_link_id_valid;
/* Bridged call info */
struct q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
int changestatus; /* SERVICE message changestatus */
int reversecharge; /* Reverse charging indication:
@@ -582,14 +516,11 @@ struct q931_call {
0,2-7 - Reserved for future use */
int t303_timer;
int t303_expirycnt;
int t312_timer;
int fake_clearing_timer;
int hangupinitiated;
/*! \brief TRUE if we broadcast this call's SETUP message. */
int outboundbroadcast;
/*! TRUE if the master call is processing a hangup. Don't destroy it now. */
int master_hanging_up;
int performing_fake_clearing;
/*!
* \brief Master call controlling this call.
* \note Always valid. Master and normal calls point to self.
@@ -599,317 +530,6 @@ struct q931_call {
/* These valid in master call only */
struct q931_call *subcalls[Q931_MAX_TEI];
int pri_winner;
/* Call completion */
struct {
/*!
* \brief CC record associated with this call.
* \note
* CC signaling link or original call when cc-available indicated.
*/
struct pri_cc_record *record;
/*! Original calling party. */
struct q931_party_id party_a;
/*! Saved BC, HLC, and LLC from initial SETUP */
struct q931_saved_ie_contents saved_ie_contents;
/*! Only save the first of each BC, HLC, and LLC from the initial SETUP. */
unsigned char saved_ie_flags;
/*! TRUE if call needs to be hung up. */
unsigned char hangup_call;
/*! TRUE if we originated this call. */
unsigned char originated;
/*! TRUE if outgoing call was already redirected. */
unsigned char initially_redirected;
} cc;
/*! Display text ie contents. */
struct {
/*! Display ie text. NULL if not present or consumed as remote name. */
const unsigned char *text;
/*! Full IE code of received display text */
int full_ie;
/*! Length of display text. */
unsigned char length;
/*!
* \brief Character set the text is using.
* \details
* unknown(0),
* iso8859-1(1),
* enum-value-withdrawn-by-ITU-T(2)
* iso8859-2(3),
* iso8859-3(4),
* iso8859-4(5),
* iso8859-5(6),
* iso8859-7(7),
* iso10646-BmpString(8),
* iso10646-utf-8String(9)
*/
unsigned char char_set;
} display;
/*! AOC charge requesting on Setup */
int aoc_charging_request;
/*! TRUE if the slotmap is E1 (32 bits). */
unsigned int slotmap_size:1;
/*! TRUE if need to see the channel id ie in first response to SETUP. */
unsigned int channel_id_ie_mandatory:1;
/*! Control the RESTART reception to the upper layer. */
struct {
/*! Timer ID of RESTART notification events to upper layer. */
int timer;
/*! Current RESTART notification index. */
int idx;
/*! Number of channels in the channel ID list. */
int count;
/*! Channel ID list */
char chan_no[32];
} restart;
/*! Control the RESTART retransmissions. */
struct {
/*! T316 RESTART retransmit timer. */
int t316_timer;
/*! Number of times remaining that RESTART can be transmitted. */
int remain;
/*! Encoded RESTART channel id. */
int channel;
} restart_tx;
};
enum CC_STATES {
/*! CC is not active. */
CC_STATE_IDLE,
// /*! CC has recorded call information in anticipation of CC availability. */
// CC_STATE_RECORD_RETENTION,
/*! CC is available and waiting on ALERTING or DISCONNECT to go out. */
CC_STATE_PENDING_AVAILABLE,
/*! CC is available and waiting on possible CC request. */
CC_STATE_AVAILABLE,
/*! CC is requested to be activated and waiting on party B to acknowledge. */
CC_STATE_REQUESTED,
/*! CC is activated and waiting for party B to become available. */
CC_STATE_ACTIVATED,
/*! CC party B is available and waiting for status of party A. */
CC_STATE_B_AVAILABLE,
/*! CC is suspended because party A is not available. (Monitor party A.) */
CC_STATE_SUSPENDED,
/*! CC is waiting for party A to initiate CC callback. */
CC_STATE_WAIT_CALLBACK,
/*! CC callback in progress. */
CC_STATE_CALLBACK,
/*! CC is waiting for signaling link to be cleared before destruction. */
CC_STATE_WAIT_DESTRUCTION,
/*! Number of CC states. Must be last in enum. */
CC_STATE_NUM
};
enum CC_EVENTS {
/*! CC is available for the current call. */
CC_EVENT_AVAILABLE,
/*! Requesting CC activation. */
CC_EVENT_CC_REQUEST,
/*! Requesting CC activation accepted. */
CC_EVENT_CC_REQUEST_ACCEPT,
/*! Requesting CC activation failed (error/reject received). */
CC_EVENT_CC_REQUEST_FAIL,
/*! CC party B is available, party A is considered free. */
CC_EVENT_REMOTE_USER_FREE,
/*! CC party B is available, party A is busy or CCBS busy. */
CC_EVENT_B_FREE,
/*! Someone else responded to the CC recall. */
CC_EVENT_STOP_ALERTING,
/*! CC poll/prompt for party A status. */
CC_EVENT_A_STATUS,
/*! CC party A is free/available for recall. */
CC_EVENT_A_FREE,
/*! CC party A is busy/not-available for recall. */
CC_EVENT_A_BUSY,
/*! Suspend monitoring party B because party A is busy. */
CC_EVENT_SUSPEND,
/*! Resume monitoring party B because party A is now available. */
CC_EVENT_RESUME,
/*! This is the CC recall call attempt. */
CC_EVENT_RECALL,
/*! Link request to cancel/deactivate CC received. */
CC_EVENT_LINK_CANCEL,
/*! Tear down CC request from upper layer. */
CC_EVENT_CANCEL,
/*! Abnormal clearing of original call. (T309 processing/T309 timeout/TEI removal) */
CC_EVENT_INTERNAL_CLEARING,
/*! Received message indicating tear down of CC signaling link completed. */
CC_EVENT_SIGNALING_GONE,
/*! Delayed hangup request for the signaling link to allow subcmd events to be passed up. */
CC_EVENT_HANGUP_SIGNALING,
/*! Sent ALERTING message. */
CC_EVENT_MSG_ALERTING,
/*! Sent DISCONNECT message. */
CC_EVENT_MSG_DISCONNECT,
/*! Sent RELEASE message. */
CC_EVENT_MSG_RELEASE,
/*! Sent RELEASE_COMPLETE message. */
CC_EVENT_MSG_RELEASE_COMPLETE,
/*! T_ACTIVATE timer timed out. */
CC_EVENT_TIMEOUT_T_ACTIVATE,
#if 0
/*! T_DEACTIVATE timer timed out. */
CC_EVENT_TIMEOUT_T_DEACTIVATE,
/*! T_INTERROGATE timer timed out. */
CC_EVENT_TIMEOUT_T_INTERROGATE,
#endif
/*! T_RETENTION timer timed out. */
CC_EVENT_TIMEOUT_T_RETENTION,
/*! T-STATUS timer equivalent for CC user A status timed out. */
CC_EVENT_TIMEOUT_T_CCBS1,
/*! Timeout for valid party A status. */
CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1,
/*! Max time the CCBS/CCNR service will be active. */
CC_EVENT_TIMEOUT_T_SUPERVISION,
/*! Max time to wait for user A to respond to user B availability. */
CC_EVENT_TIMEOUT_T_RECALL,
};
enum CC_PARTY_A_AVAILABILITY {
CC_PARTY_A_AVAILABILITY_INVALID,
CC_PARTY_A_AVAILABILITY_BUSY,
CC_PARTY_A_AVAILABILITY_FREE,
};
/* Invalid PTMP call completion reference and linkage id value. */
#define CC_PTMP_INVALID_ID 0xFF
/*! \brief Call-completion record */
struct pri_cc_record {
/*! Next call-completion record in the list */
struct pri_cc_record *next;
/*! D channel control structure. */
struct pri *ctrl;
/*! Original call that is offered CC availability. (NULL if no longer exists.) */
struct q931_call *original_call;
/*!
* \brief Associated signaling link. (NULL if not established.)
* \note
* PTMP - Broadcast dummy call reference call.
* (If needed, the TE side could use this pointer to locate its specific
* dummy call reference call.)
* \note
* PTP - REGISTER signaling link.
* \note
* Q.SIG - SETUP signaling link.
*/
struct q931_call *signaling;
/*! Call-completion record id (0 - 65535) */
long record_id;
/*! Call-completion state */
enum CC_STATES state;
/*! Original calling party. */
struct q931_party_id party_a;
/*! Original called party. */
struct q931_party_address party_b;
/*! Saved BC, HLC, and LLC from initial SETUP */
struct q931_saved_ie_contents saved_ie_contents;
/*! Saved decoded BC */
struct decoded_bc bc;
/*! FSM parameters. */
union {
/*! PTMP FSM parameters. */
struct {
/*! Extended T_CCBS1 timer id for CCBSStatusRequest handling. */
int extended_t_ccbs1;
/*! Invoke id for the CCBSStatusRequest message to find if T_CCBS1 still running. */
int t_ccbs1_invoke_id;
/*! Number of times party A status request got no responses. */
int party_a_status_count;
/*! Accumulating party A availability status */
enum CC_PARTY_A_AVAILABILITY party_a_status_acc;
} ptmp;
/*! PTP FSM parameters. */
struct {
} ptp;
struct {
/*! Q.931 message type the current message event came in on. */
int msgtype;
} qsig;
} fsm;
/*! Received message parameters of interest. */
union {
/*! cc-request error/reject response */
struct {
/*! enum APDU_CALLBACK_REASON reason */
int reason;
/*! MSG_ERROR/MSG_REJECT fail code. */
int code;
} cc_req_rsp;
} msg;
/*! Party A availability status */
enum CC_PARTY_A_AVAILABILITY party_a_status;
/*! Indirect timer id to abort indirect action events. */
int t_indirect;
/*!
* \brief PTMP T_RETENTION timer id.
* \note
* This timer is used by all CC agents to implement
* the Asterisk CC core offer timer.
*/
int t_retention;
/*!
* \brief CC service supervision timer.
*
* \details
* This timer is one of the following timer id's depending upon
* switch type and CC mode:
* PTMP - T_CCBS2/T_CCNR2,
* PTP - T_CCBS5/T_CCNR5/T_CCBS6/T_CCNR6,
* Q.SIG - QSIG_CCBS_T2/QSIG_CCNR_T2
*/
int t_supervision;
/*!
* \brief Party A response to B availability for recall timer.
* \details
* This timer is one of the following timer id's:
* PTMP - T_CCBS3
* Q.SIG - QSIG_CC_T3
*/
int t_recall;
/*! Invoke id for the cc-request message to find if T_ACTIVATE/QSIG_CC_T1 still running. */
int t_activate_invoke_id;
/*! Pending response information. */
struct {
/*!
* \brief Send response on this signaling link.
* \note Used by PTMP for CCBSRequest/CCNRRequest/CCBSCall responses.
* \note Used by Q.SIG for ccRingout responses.
*/
struct q931_call *signaling;
/*! Invoke operation code */
int invoke_operation;
/*! Invoke id to use in the pending response. */
short invoke_id;
} response;
/*! TRUE if the call-completion FSM has completed and this record needs to be destroyed. */
unsigned char fsm_complete;
/*! TRUE if we are a call completion agent. */
unsigned char is_agent;
/*! TRUE if active cc mode is CCNR. */
unsigned char is_ccnr;
/*! PTMP pre-activation reference id. (0-127) */
unsigned char call_linkage_id;
/*! PTMP active CCBS reference id. (0-127) */
unsigned char ccbs_reference_id;
/*! Negotiated options */
struct {
/*! PTMP recall mode: globalRecall(0), specificRecall(1) */
unsigned char recall_mode;
/*! TRUE if negotiated for Q.SIG signaling link to be retained. */
unsigned char retain_signaling_link;
#if defined(QSIG_PATH_RESERVATION_SUPPORT)
/*! Q.SIG TRUE if can do path reservation. */
unsigned char do_path_reservation;
#endif /* defined(QSIG_PATH_RESERVATION_SUPPORT) */
} option;
};
/*! D channel control structure with associated dummy call reference record. */
@@ -920,35 +540,11 @@ struct d_ctrl_dummy {
struct q931_call dummy_call;
};
/*! Layer 2 link control structure with associated dummy call reference record. */
struct link_dummy {
/*! Layer 2 control structure. Must be first in the structure. */
struct q921_link link;
/*! Dummy call reference call record. */
struct q931_call dummy_call;
};
/*!
* \brief Check if the given call ptr is valid and gripe if not.
*
* \param ctrl D channel controller.
* \param call Q.931 call leg.
*
* \retval TRUE if call ptr is valid.
* \retval FALSE if call ptr is invalid.
*/
#define pri_is_call_valid(ctrl, call) \
q931_is_call_valid_gripe(ctrl, call, __PRETTY_FUNCTION__, __LINE__)
int q931_is_call_valid(struct pri *ctrl, struct q931_call *call);
int q931_is_call_valid_gripe(struct pri *ctrl, struct q931_call *call, const char *func_name, unsigned long func_line);
unsigned pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data);
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
extern pri_event *pri_schedule_run(struct pri *pri);
void pri_schedule_del(struct pri *ctrl, unsigned id);
int pri_schedule_check(struct pri *ctrl, unsigned id, void (*function)(void *data), void *data);
extern void pri_schedule_del(struct pri *pri, int ev);
extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
@@ -957,12 +553,10 @@ void pri_error(struct pri *ctrl, const char *fmt, ...) __attribute__((format(pri
void libpri_copy_string(char *dst, const char *src, size_t size);
void pri_link_destroy(struct q921_link *link);
struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei);
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri);
void __pri_free_tei(struct pri *p);
void q931_init_call_record(struct q921_link *link, struct q931_call *call, int cr);
void pri_sr_init(struct pri_sr *req);
void q931_init_call_record(struct pri *ctrl, struct q931_call *call, int cr);
void q931_party_name_init(struct q931_party_name *name);
void q931_party_number_init(struct q931_party_number *number);
@@ -971,32 +565,20 @@ void q931_party_address_init(struct q931_party_address *address);
void q931_party_id_init(struct q931_party_id *id);
void q931_party_redirecting_init(struct q931_party_redirecting *redirecting);
static inline void q931_party_address_to_id(struct q931_party_id *id, const struct q931_party_address *address)
static inline void q931_party_address_to_id(struct q931_party_id *id, struct q931_party_address *address)
{
id->number = address->number;
id->subaddress = address->subaddress;
}
static inline void q931_party_id_to_address(struct q931_party_address *address, const struct q931_party_id *id)
{
address->number = id->number;
address->subaddress = id->subaddress;
}
int q931_party_name_cmp(const struct q931_party_name *left, const struct q931_party_name *right);
int q931_party_number_cmp(const struct q931_party_number *left, const struct q931_party_number *right);
int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right);
int q931_party_address_cmp(const struct q931_party_address *left, const struct q931_party_address *right);
int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_id *right);
int q931_party_id_cmp_address(const struct q931_party_id *left, const struct q931_party_id *right);
int q931_cmp_party_id_to_address(const struct q931_party_id *id, const struct q931_party_address *address);
void q931_party_id_copy_to_address(struct q931_party_address *address, const struct q931_party_id *id);
void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q931_party_name *q931_name);
void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const struct q931_party_number *q931_number);
void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress);
void q931_party_address_copy_to_pri(struct pri_party_address *pri_address, const struct q931_party_address *q931_address);
void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_party_id *q931_id);
void q931_party_redirecting_copy_to_pri(struct pri_party_redirecting *pri_redirecting, const struct q931_party_redirecting *q931_redirecting);
@@ -1008,48 +590,24 @@ void pri_copy_party_id_to_q931(struct q931_party_id *q931_id, const struct pri_p
void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id);
int q931_party_id_presentation(const struct q931_party_id *id);
int q931_display_name_get(struct q931_call *call, struct q931_party_name *name);
int q931_display_text(struct pri *ctrl, struct q931_call *call, const struct pri_subcmd_display_txt *display);
int q931_facility_display_name(struct pri *ctrl, struct q931_call *call, const struct q931_party_name *name);
int q931_facility_called(struct pri *ctrl, struct q931_call *call, const struct q931_party_id *called);
const char *q931_call_state_str(enum Q931_CALL_STATE callstate);
const char *msg2str(int msg);
int q931_get_subcall_count(struct q931_call *master);
struct q931_call *q931_find_winning_call(struct q931_call *call);
int q931_master_pass_event(struct pri *ctrl, struct q931_call *subcall, int msg_type);
struct pri_subcommand *q931_alloc_subcommand(struct pri *ctrl);
struct q931_call *q931_find_link_id_call(struct pri *ctrl, int link_id);
struct q931_call *q931_find_held_active_call(struct pri *ctrl, struct q931_call *held_call);
int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number);
int q931_subaddress_transfer(struct pri *ctrl, struct q931_call *call);
int q931_notify_redirection(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number);
struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id);
struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id);
struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b, unsigned length, const unsigned char *q931_ies);
struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call);
void pri_cc_qsig_determine_available(struct pri *ctrl, q931_call *call);
const char *pri_cc_fsm_state_str(enum CC_STATES state);
const char *pri_cc_fsm_event_str(enum CC_EVENTS event);
int pri_cc_event(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event);
int q931_cc_timeout(struct pri *ctrl, struct pri_cc_record *cc_record, enum CC_EVENTS event);
void q931_cc_indirect(struct pri *ctrl, struct pri_cc_record *cc_record, void (*func)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record));
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
/*!
* \brief Get the NFAS master PRI control structure.
* \brief Get the master PRI control structure.
*
* \param ctrl D channel controller.
*
* \return NFAS master PRI control structure.
* \return Master PRI control structure.
*/
static inline struct pri *PRI_NFAS_MASTER(struct pri *ctrl)
static inline struct pri *PRI_MASTER(struct pri *ctrl)
{
if (ctrl->master) {
while (ctrl->master) {
ctrl = ctrl->master;
}
return ctrl;
@@ -1067,8 +625,10 @@ static inline int BRI_NT_PTMP(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->bri && my_ctrl->localtype == PRI_NETWORK
&& my_ctrl->link.tei == Q921_TEI_GROUP;
&& my_ctrl->tei == Q921_TEI_GROUP;
}
/*!
@@ -1083,8 +643,10 @@ static inline int BRI_TE_PTMP(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->bri && my_ctrl->localtype == PRI_CPE
&& my_ctrl->link.tei == Q921_TEI_GROUP;
&& my_ctrl->tei == Q921_TEI_GROUP;
}
/*!
@@ -1099,6 +661,8 @@ static inline int NT_MODE(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->localtype == PRI_NETWORK;
}
@@ -1114,6 +678,8 @@ static inline int TE_MODE(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->localtype == PRI_CPE;
}
@@ -1129,7 +695,9 @@ static inline int PTP_MODE(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
return my_ctrl->link.tei == Q921_TEI_PRI;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->tei == Q921_TEI_PRI;
}
/*!
@@ -1144,7 +712,9 @@ static inline int PTMP_MODE(const struct pri *ctrl)
{
struct pri *my_ctrl = (struct pri *) ctrl;
return my_ctrl->link.tei == Q921_TEI_GROUP;
/* Check master control structure */
my_ctrl = PRI_MASTER(my_ctrl);
return my_ctrl->tei == Q921_TEI_GROUP;
}
#define Q931_DUMMY_CALL_REFERENCE -1
@@ -1156,14 +726,9 @@ static inline int PTMP_MODE(const struct pri *ctrl)
* \retval TRUE if given call is a dummy call.
* \retval FALSE otherwise.
*/
static inline int q931_is_dummy_call(const struct q931_call *call)
static inline int q931_is_dummy_call(const q931_call *call)
{
return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
}
static inline short get_invokeid(struct pri *ctrl)
{
return ++ctrl->last_invoke;
}
#endif

View File

@@ -57,8 +57,6 @@
#define Q921_TEI_GR303_EOC_OPS 4
#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,16 +69,13 @@
#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,
};
#define Q921_TEI_IDENTITY_REQUEST 1
#define Q921_TEI_IDENTITY_ASSIGNED 2
#define Q921_TEI_IDENTITY_DENIED 3
#define Q921_TEI_IDENTITY_CHECK_REQUEST 4
#define Q921_TEI_IDENTITY_CHECK_RESPONSE 5
#define Q921_TEI_IDENTITY_REMOVE 6
#define Q921_TEI_IDENTITY_VERIFY 7
typedef struct q921_header {
#if __BYTE_ORDER == __BIG_ENDIAN
@@ -163,17 +158,11 @@ 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)
@@ -191,101 +180,24 @@ typedef enum q921_state {
Q921_TIMER_RECOVERY = 8,
} 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(struct pri *pri, 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);
//extern void q921_reset(struct pri *pri, int reset_iqueue);
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);
extern int q921_transmit_iframe(struct pri *pri, int tei, void *buf, int len, int cr);
int q921_transmit_uiframe(struct q921_link *link, void *buf, int len);
extern int q921_transmit_uiframe(struct pri *pri, void *buf, int len);
extern pri_event *q921_dchannel_up(struct pri *pri);

View File

@@ -82,9 +82,6 @@ typedef struct q931_ie {
/* 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 +106,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 */
@@ -138,6 +134,9 @@ typedef struct q931_ie {
#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
@@ -440,8 +439,6 @@ enum Q931_RANKED_CALL_STATE {
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 */
@@ -449,11 +446,13 @@ enum Q931_RANKED_CALL_STATE {
extern int maintenance_service(struct pri *pri, int span, int channel, int changestatus);
extern int maintenance_service_ack(struct pri *pri, q931_call *call);
/* Q.SIG specific */
#define QSIG_IE_TRANSIT_COUNT 0x31
int q931_receive(struct q921_link *link, q931_h *h, int len);
extern int q931_receive(struct pri *pri, int tei, q931_h *h, int len);
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
@@ -465,14 +464,13 @@ 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);
@@ -488,25 +486,15 @@ 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);
struct q931_call *q931_find_call(struct pri *ctrl, int cr);
struct q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
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);
extern void q931_dl_indication(struct pri *pri, int event);
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);

View File

@@ -42,7 +42,7 @@
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <dahdi/user.h>
#include <zaptel/zaptel.h>
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"
@@ -50,18 +50,18 @@
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;
}
@@ -71,7 +71,7 @@ static int pri_open(char *dev)
static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
{
q921_h *h = (q921_h *)buf;
q921_dump(pri, h, len, PRI_DEBUG_ALL, txrx);
q921_dump(pri, h, len, 1, txrx);
if (!((h->h.data[0] & Q921_FRAMETYPE_MASK) & 0x3)) {
q931_dump(pri, h->h.tei, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
}
@@ -80,7 +80,7 @@ static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
}
static void pri_bridge(int d1, int d2)
static int pri_bridge(int d1, int d2)
{
char buf[1024];
fd_set fds;
@@ -94,8 +94,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));

View File

@@ -28,92 +28,16 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libpri.h"
#include "pri_internal.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)
{
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. */
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.
*
@@ -125,25 +49,24 @@ static int pri_schedule_grow(struct pri *ctrl)
* \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)
int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data)
{
unsigned max_used;
unsigned x;
int x;
struct timeval tv;
max_used = ctrl->sched.max_used;
for (x = 0; x < max_used; ++x) {
if (!ctrl->sched.timer[x].callback) {
/* Scheduling runs on master channels only */
while (ctrl->master) {
ctrl = ctrl->master;
}
for (x = 0; x < MAX_SCHED; ++x) {
if (!ctrl->pri_sched[x].callback) {
break;
}
}
if (x == ctrl->sched.num_slots && pri_schedule_grow(ctrl)) {
if (x == MAX_SCHED) {
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;
}
@@ -154,10 +77,10 @@ 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;
ctrl->pri_sched[x].when = tv;
ctrl->pri_sched[x].callback = function;
ctrl->pri_sched[x].data = data;
return x + 1;
}
/*!
@@ -170,25 +93,19 @@ unsigned pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *dat
struct timeval *pri_schedule_next(struct pri *ctrl)
{
struct timeval *closest = NULL;
unsigned x;
int 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;
}
}
/* Scheduling runs on master channels only */
while (ctrl->master) {
ctrl = ctrl->master;
}
if (!closest) {
/* No scheduled timer slots are active. */
ctrl->sched.max_used = 0;
for (x = 0; x < MAX_SCHED; ++x) {
if (ctrl->pri_sched[x].callback && (!closest
|| (closest->tv_sec > ctrl->pri_sched[x].when.tv_sec)
|| ((closest->tv_sec == ctrl->pri_sched[x].when.tv_sec)
&& (closest->tv_usec > ctrl->pri_sched[x].when.tv_usec)))) {
closest = &ctrl->pri_sched[x].when;
}
}
return closest;
}
@@ -204,22 +121,23 @@ struct timeval *pri_schedule_next(struct pri *ctrl)
*/
static pri_event *__pri_schedule_run(struct pri *ctrl, 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)))) {
/* Scheduling runs on master channels only */
while (ctrl->master) {
ctrl = ctrl->master;
}
for (x = 0; x < MAX_SCHED; ++x) {
if (ctrl->pri_sched[x].callback && ((ctrl->pri_sched[x].when.tv_sec < tv->tv_sec)
|| ((ctrl->pri_sched[x].when.tv_sec == tv->tv_sec)
&& (ctrl->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
/* This timer has expired. */
ctrl->schedev = 0;
callback = ctrl->sched.timer[x].callback;
data = ctrl->sched.timer[x].data;
ctrl->sched.timer[x].callback = NULL;
callback = ctrl->pri_sched[x].callback;
data = ctrl->pri_sched[x].data;
ctrl->pri_sched[x].callback = NULL;
callback(data);
if (ctrl->schedev) {
return &ctrl->ev;
@@ -250,73 +168,19 @@ pri_event *pri_schedule_run(struct pri *ctrl)
* \param ctrl D channel controller.
* \param id Scheduled event id to delete.
* 0 is a disabled/unscheduled event id that is ignored.
* 1 - MAX_SCHED is a valid event id.
*
* \return Nothing
*/
void pri_schedule_del(struct pri *ctrl, unsigned id)
void pri_schedule_del(struct pri *ctrl, int id)
{
struct pri *nfas;
if (!id) {
/* Disabled/unscheduled event id. */
return;
/* Scheduling runs on master channels only */
while (ctrl->master) {
ctrl = ctrl->master;
}
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 (0 < id && id <= MAX_SCHED) {
ctrl->pri_sched[id - 1].callback = NULL;
} else if (id) {
pri_error(ctrl, "Asked to delete sched id %d???\n", id);
}
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;
}

View File

@@ -28,7 +28,7 @@
*/
/*
* 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 +37,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 +45,8 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
#include <zaptel/zaptel.h>
#include <zap.h>
#include "libpri.h"
#define PRI_DEF_NODETYPE PRI_CPE
@@ -56,23 +55,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 +141,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 +161,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);
@@ -357,7 +299,7 @@ static int run_pri(int dfd, int swtype, int node)
fd_set rfds, efds;
int res,x;
pri = pri_new(dfd, node, swtype);
pri = pri_new_bri(dfd, 1, node, swtype);
if (!pri) {
fprintf(stderr, "Unable to create PRI\n");
return -1;
@@ -392,8 +334,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 +343,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 +365,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 +375,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);
}

3439
q921.c

File diff suppressed because it is too large Load Diff

4704
q931.c

File diff suppressed because it is too large Load Diff

536
rose.c
View File

@@ -200,54 +200,6 @@ static const struct asn1_oid rose_etsi_ect = {
/* *INDENT-ON* */
};
/*! \brief ETSI Status Request OID prefix. */
static const struct asn1_oid rose_etsi_status_request = {
/* *INDENT-OFF* */
/* {itu-t(0) identified-organization(4) etsi(0) 196 status-request-procedure(9)} */
4, { 4, 0, 196, 9 }
/* *INDENT-ON* */
};
/*! \brief ETSI Call Completion Busy Status OID prefix. */
static const struct asn1_oid rose_etsi_ccbs = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 359 operations-and-errors(1)} */
4, { 4, 0, 359, 1 }
/* *INDENT-ON* */
};
/*! \brief ETSI Call Completion Busy Status public-private interworking OID prefix. */
static const struct asn1_oid rose_etsi_ccbs_t = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 359 private-networks-operations-and-errors(2)} */
4, { 4, 0, 359, 2 }
/* *INDENT-ON* */
};
/*! \brief ETSI Call Completion No Reply OID prefix. */
static const struct asn1_oid rose_etsi_ccnr = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 1065 operations-and-errors(1)} */
4, { 4, 0, 1065, 1 }
/* *INDENT-ON* */
};
/*! \brief ETSI Call Completion No Reply public-private interworking OID prefix. */
static const struct asn1_oid rose_etsi_ccnr_t = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 1065 private-networks-operations-and-errors(2)} */
4, { 4, 0, 1065, 2 }
/* *INDENT-ON* */
};
/*! \brief ETSI Message Waiting Indication OID prefix. */
static const struct asn1_oid rose_etsi_mwi = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 745 operations-and-errors(1)} */
4, { 4, 0, 745, 1 }
/* *INDENT-ON* */
};
/*! \brief ETSI specific invoke/result encode/decode message table */
static const struct rose_convert_msg rose_etsi_msgs[] = {
/* *INDENT-OFF* */
@@ -409,166 +361,6 @@ static const struct rose_convert_msg rose_etsi_msgs[] = {
rose_enc_etsi_EctLoopTest_ARG, rose_enc_etsi_EctLoopTest_RES,
rose_dec_etsi_EctLoopTest_ARG, rose_dec_etsi_EctLoopTest_RES
},
/*
* globalValue's (OIDs) from Status-Request-Procedure
* {itu-t identified-organization etsi(0) 196 status-request-procedure(9)}
*/
{
ROSE_ETSI_StatusRequest, &rose_etsi_status_request, 1,
rose_enc_etsi_StatusRequest_ARG, rose_enc_etsi_StatusRequest_RES,
rose_dec_etsi_StatusRequest_ARG, rose_dec_etsi_StatusRequest_RES
},
/*
* globalValue's (OIDs) from CCBS-Operations-and-Errors
* {ccitt identified-organization etsi(0) 359 operations-and-errors(1)}
*/
{
ROSE_ETSI_CallInfoRetain, &rose_etsi_ccbs, 1,
rose_enc_etsi_CallInfoRetain_ARG, NULL,
rose_dec_etsi_CallInfoRetain_ARG, NULL
},
{
ROSE_ETSI_CCBSRequest, &rose_etsi_ccbs, 2,
rose_enc_etsi_CCBSRequest_ARG, rose_enc_etsi_CCBSRequest_RES,
rose_dec_etsi_CCBSRequest_ARG, rose_dec_etsi_CCBSRequest_RES
},
{
ROSE_ETSI_CCBSDeactivate, &rose_etsi_ccbs, 3,
rose_enc_etsi_CCBSDeactivate_ARG, NULL,
rose_dec_etsi_CCBSDeactivate_ARG, NULL
},
{
ROSE_ETSI_CCBSInterrogate, &rose_etsi_ccbs, 4,
rose_enc_etsi_CCBSInterrogate_ARG, rose_enc_etsi_CCBSInterrogate_RES,
rose_dec_etsi_CCBSInterrogate_ARG, rose_dec_etsi_CCBSInterrogate_RES
},
{
ROSE_ETSI_CCBSErase, &rose_etsi_ccbs, 5,
rose_enc_etsi_CCBSErase_ARG, NULL,
rose_dec_etsi_CCBSErase_ARG, NULL
},
{
ROSE_ETSI_CCBSRemoteUserFree, &rose_etsi_ccbs, 6,
rose_enc_etsi_CCBSRemoteUserFree_ARG, NULL,
rose_dec_etsi_CCBSRemoteUserFree_ARG, NULL
},
{
ROSE_ETSI_CCBSCall, &rose_etsi_ccbs, 7,
rose_enc_etsi_CCBSCall_ARG, NULL,
rose_dec_etsi_CCBSCall_ARG, NULL
},
{
ROSE_ETSI_CCBSStatusRequest, &rose_etsi_ccbs, 8,
rose_enc_etsi_CCBSStatusRequest_ARG, rose_enc_etsi_CCBSStatusRequest_RES,
rose_dec_etsi_CCBSStatusRequest_ARG, rose_dec_etsi_CCBSStatusRequest_RES
},
{
ROSE_ETSI_CCBSBFree, &rose_etsi_ccbs, 9,
rose_enc_etsi_CCBSBFree_ARG, NULL,
rose_dec_etsi_CCBSBFree_ARG, NULL
},
{
ROSE_ETSI_EraseCallLinkageID, &rose_etsi_ccbs, 10,
rose_enc_etsi_EraseCallLinkageID_ARG, NULL,
rose_dec_etsi_EraseCallLinkageID_ARG, NULL
},
{
ROSE_ETSI_CCBSStopAlerting, &rose_etsi_ccbs, 11,
rose_enc_etsi_CCBSStopAlerting_ARG, NULL,
rose_dec_etsi_CCBSStopAlerting_ARG, NULL
},
/*
* globalValue's (OIDs) from CCBS-private-networks-Operations-and-Errors
* {ccitt identified-organization etsi(0) 359 private-networks-operations-and-errors(2)}
*/
{
ROSE_ETSI_CCBS_T_Request, &rose_etsi_ccbs_t, 1,
rose_enc_etsi_CCBS_T_Request_ARG, rose_enc_etsi_CCBS_T_Request_RES,
rose_dec_etsi_CCBS_T_Request_ARG, rose_dec_etsi_CCBS_T_Request_RES
},
{
ROSE_ETSI_CCBS_T_Call, &rose_etsi_ccbs_t, 2,
NULL, NULL,
NULL, NULL
},
{
ROSE_ETSI_CCBS_T_Suspend, &rose_etsi_ccbs_t, 3,
NULL, NULL,
NULL, NULL
},
{
ROSE_ETSI_CCBS_T_Resume, &rose_etsi_ccbs_t, 4,
NULL, NULL,
NULL, NULL
},
{
ROSE_ETSI_CCBS_T_RemoteUserFree, &rose_etsi_ccbs_t, 5,
NULL, NULL,
NULL, NULL
},
{
ROSE_ETSI_CCBS_T_Available, &rose_etsi_ccbs_t, 6,
NULL, NULL,
NULL, NULL
},
/*
* globalValue's (OIDs) from CCNR-Operations-and-Errors
* {ccitt identified-organization etsi(0) 1065 operations-and-errors(1)}
*/
{
ROSE_ETSI_CCNRRequest, &rose_etsi_ccnr, 1,
rose_enc_etsi_CCNRRequest_ARG, rose_enc_etsi_CCNRRequest_RES,
rose_dec_etsi_CCNRRequest_ARG, rose_dec_etsi_CCNRRequest_RES
},
{
ROSE_ETSI_CCNRInterrogate, &rose_etsi_ccnr, 2,
rose_enc_etsi_CCNRInterrogate_ARG, rose_enc_etsi_CCNRInterrogate_RES,
rose_dec_etsi_CCNRInterrogate_ARG, rose_dec_etsi_CCNRInterrogate_RES
},
/*
* globalValue's (OIDs) from CCNR-private-networks-Operations-and-Errors
* {ccitt identified-organization etsi(0) 1065 private-networks-operations-and-errors(2)}
*/
{
ROSE_ETSI_CCNR_T_Request, &rose_etsi_ccnr_t, 1,
rose_enc_etsi_CCNR_T_Request_ARG, rose_enc_etsi_CCNR_T_Request_RES,
rose_dec_etsi_CCNR_T_Request_ARG, rose_dec_etsi_CCNR_T_Request_RES
},
/*
* localValue's from MCID-Operations
* {ccitt identified-organization etsi(0) 130 operations-and-errors(1)}
*/
{
ROSE_ETSI_MCIDRequest, NULL, 3,
NULL, NULL,
NULL, NULL
},
/*
* globalValue's (OIDs) from MWI-Operations-and-Errors
* {ccitt identified-organization etsi(0) 745 operations-and-errors(1)}
*/
{
ROSE_ETSI_MWIActivate, &rose_etsi_mwi, 1,
rose_enc_etsi_MWIActivate_ARG, NULL,
rose_dec_etsi_MWIActivate_ARG, NULL
},
{
ROSE_ETSI_MWIDeactivate, &rose_etsi_mwi, 2,
rose_enc_etsi_MWIDeactivate_ARG, NULL,
rose_dec_etsi_MWIDeactivate_ARG, NULL
},
{
ROSE_ETSI_MWIIndicate, &rose_etsi_mwi, 3,
rose_enc_etsi_MWIIndicate_ARG, NULL,
rose_dec_etsi_MWIIndicate_ARG, NULL
},
/* *INDENT-ON* */
};
@@ -671,89 +463,6 @@ static const struct rose_convert_error rose_etsi_errors[] = {
ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork, &rose_etsi_ect, 21,
NULL, NULL
},
/*
* globalValue Errors (OIDs) from CCBS-Operations-and-Errors
* {ccitt identified-organization etsi(0) 359 operations-and-errors(1)}
*/
{
ROSE_ERROR_CCBS_InvalidCallLinkageID, &rose_etsi_ccbs, 20,
NULL, NULL
},
{
ROSE_ERROR_CCBS_InvalidCCBSReference, &rose_etsi_ccbs, 21,
NULL, NULL
},
{
ROSE_ERROR_CCBS_LongTermDenial, &rose_etsi_ccbs, 22,
NULL, NULL
},
{
ROSE_ERROR_CCBS_ShortTermDenial, &rose_etsi_ccbs, 23,
NULL, NULL
},
{
ROSE_ERROR_CCBS_IsAlreadyActivated, &rose_etsi_ccbs, 24,
NULL, NULL
},
{
ROSE_ERROR_CCBS_AlreadyAccepted, &rose_etsi_ccbs, 25,
NULL, NULL
},
{
ROSE_ERROR_CCBS_OutgoingCCBSQueueFull, &rose_etsi_ccbs, 26,
NULL, NULL
},
{
ROSE_ERROR_CCBS_CallFailureReasonNotBusy, &rose_etsi_ccbs, 27,
NULL, NULL
},
{
ROSE_ERROR_CCBS_NotReadyForCall, &rose_etsi_ccbs, 28,
NULL, NULL
},
/*
* globalValue Errors (OIDs) from CCBS-private-networks-Operations-and-Errors
* {ccitt identified-organization etsi(0) 359 private-networks-operations-and-errors(2)}
*/
{
ROSE_ERROR_CCBS_T_LongTermDenial, &rose_etsi_ccbs_t, 20,
NULL, NULL
},
{
ROSE_ERROR_CCBS_T_ShortTermDenial, &rose_etsi_ccbs_t, 21,
NULL, NULL
},
/*
* globalValue's (OIDs) from MWI-Operations-and-Errors
* {ccitt identified-organization etsi(0) 745 operations-and-errors(1)}
*/
{
ROSE_ERROR_MWI_InvalidReceivingUserNr, &rose_etsi_mwi, 10,
NULL, NULL
},
{
ROSE_ERROR_MWI_ReceivingUserNotSubscribed, &rose_etsi_mwi, 11,
NULL, NULL
},
{
ROSE_ERROR_MWI_ControllingUserNotRegistered,&rose_etsi_mwi, 12,
NULL, NULL
},
{
ROSE_ERROR_MWI_IndicationNotDelivered, &rose_etsi_mwi, 13,
NULL, NULL
},
{
ROSE_ERROR_MWI_MaxNumOfControllingUsersReached,&rose_etsi_mwi, 14,
NULL, NULL
},
{
ROSE_ERROR_MWI_MaxNumOfActiveInstancesReached,&rose_etsi_mwi, 15,
NULL, NULL
},
/* *INDENT-ON* */
};
@@ -761,21 +470,6 @@ static const struct rose_convert_error rose_etsi_errors[] = {
/* ------------------------------------------------------------------- */
/*
* Note the first value in oid.values[] is really the first two
* OID subidentifiers. They are compressed using this formula:
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
*/
/*! \brief ECMA private-isdn-signalling-domain prefix. */
static const struct asn1_oid rose_qsig_isdn_domain = {
/* *INDENT-OFF* */
/* {iso(1) identified-organization(3) icd-ecma(12) private-isdn-signalling-domain(9)} */
3, { 43, 12, 9 }
/* *INDENT-ON* */
};
/*! \brief Q.SIG specific invoke/result encode/decode message table */
static const struct rose_convert_msg rose_qsig_msgs[] = {
/* *INDENT-OFF* */
@@ -785,7 +479,7 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
* decode_invoke_args, decode_result_args
*/
/*
* localValue's from Q.SIG Name-Operations 4th edition
* localValue's from Q.SIG Name-Operations
* { iso(1) standard(0) pss1-name(13868) name-operations(0) }
*/
{
@@ -809,34 +503,6 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
rose_dec_qsig_BusyName_ARG, NULL
},
/*
* globalValue's (OIDs) from Q.SIG Name-Operations 2nd edition
* { iso(1) identified-organization(3) icd-ecma(12) standard(0) qsig-name(164) name-operations(0) }
*
* This older version of the Q.SIG switch is not supported.
* However, we will accept receiving these messages anyway.
*/
{
ROSE_QSIG_CallingName, &rose_qsig_isdn_domain, 0,
rose_enc_qsig_CallingName_ARG, NULL,
rose_dec_qsig_CallingName_ARG, NULL
},
{
ROSE_QSIG_CalledName, &rose_qsig_isdn_domain, 1,
rose_enc_qsig_CalledName_ARG, NULL,
rose_dec_qsig_CalledName_ARG, NULL
},
{
ROSE_QSIG_ConnectedName, &rose_qsig_isdn_domain, 2,
rose_enc_qsig_ConnectedName_ARG, NULL,
rose_dec_qsig_ConnectedName_ARG, NULL
},
{
ROSE_QSIG_BusyName, &rose_qsig_isdn_domain, 3,
rose_enc_qsig_BusyName_ARG, NULL,
rose_dec_qsig_BusyName_ARG, NULL
},
/*
* localValue's from Q.SIG SS-AOC-Operations
* { iso(1) standard(0) pss1-advice-of-charge(15050) advice-of-charge-operations(0) }
@@ -983,51 +649,6 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
rose_dec_qsig_DummyArg_ARG, NULL
},
/*
* localValue's from Q.SIG SS-CC-Operations
* { iso(1) standard(0) pss1-call-completion(13870) operations(0) }
*/
{
ROSE_QSIG_CcbsRequest, NULL, 40,
rose_enc_qsig_CcbsRequest_ARG, rose_enc_qsig_CcbsRequest_RES,
rose_dec_qsig_CcbsRequest_ARG, rose_dec_qsig_CcbsRequest_RES
},
{
ROSE_QSIG_CcnrRequest, NULL, 27,
rose_enc_qsig_CcnrRequest_ARG, rose_enc_qsig_CcnrRequest_RES,
rose_dec_qsig_CcnrRequest_ARG, rose_dec_qsig_CcnrRequest_RES
},
{
ROSE_QSIG_CcCancel, NULL, 28,
rose_enq_qsig_CcCancel_ARG, NULL,
rose_dec_qsig_CcCancel_ARG, NULL
},
{
ROSE_QSIG_CcExecPossible, NULL, 29,
rose_enq_qsig_CcExecPossible_ARG, NULL,
rose_dec_qsig_CcExecPossible_ARG, NULL
},
{
ROSE_QSIG_CcPathReserve, NULL, 30,
rose_enc_qsig_CcPathReserve_ARG, rose_enc_qsig_CcPathReserve_RES,
rose_dec_qsig_CcPathReserve_ARG, rose_dec_qsig_CcPathReserve_RES
},
{
ROSE_QSIG_CcRingout, NULL, 31,
rose_enc_qsig_CcRingout_ARG, NULL,
rose_dec_qsig_CcRingout_ARG, NULL
},
{
ROSE_QSIG_CcSuspend, NULL, 32,
rose_enc_qsig_CcSuspend_ARG, NULL,
rose_dec_qsig_CcSuspend_ARG, NULL
},
{
ROSE_QSIG_CcResume, NULL, 33,
rose_enc_qsig_CcResume_ARG, NULL,
rose_dec_qsig_CcResume_ARG, NULL
},
/*
* localValue's from Q.SIG SS-MWI-Operations
* { iso(1) standard(0) pss1-message-waiting-indication(15506) message-waiting-operations(0) }
@@ -1179,31 +800,6 @@ static const struct rose_convert_error rose_qsig_errors[] = {
NULL, NULL
},
/*
* localValue's from Q.SIG SS-CC-Operations
* { iso(1) standard(0) pss1-call-completion(13870) operations(0) }
*/
{
ROSE_ERROR_QSIG_ShortTermRejection, NULL, 1010,
NULL, NULL
},
{
ROSE_ERROR_QSIG_LongTermRejection, NULL, 1011,
NULL, NULL
},
{
ROSE_ERROR_QSIG_RemoteUserBusyAgain, NULL, 1012,
NULL, NULL
},
{
ROSE_ERROR_QSIG_FailureToMatch, NULL, 1013,
NULL, NULL
},
{
ROSE_ERROR_QSIG_FailedDueToInterworking, NULL, 1014,
NULL, NULL
},
/*
* localValue's from Q.SIG SS-MWI-Operations
* { iso(1) standard(0) pss1-message-waiting-indication(15506) message-waiting-operations(0) }
@@ -1237,34 +833,6 @@ static const struct rose_convert_msg rose_dms100_msgs[] = {
rose_enc_dms100_RLT_ThirdParty_ARG, NULL,
rose_dec_dms100_RLT_ThirdParty_ARG, NULL
},
/* DMS-100 seems to have pirated some Q.SIG messages */
/*
* localValue's from Q.SIG Name-Operations
* { iso(1) standard(0) pss1-name(13868) name-operations(0) }
*/
{
ROSE_QSIG_CallingName, NULL, 0,
rose_enc_qsig_CallingName_ARG, NULL,
rose_dec_qsig_CallingName_ARG, NULL
},
#if 0 /* ROSE_DMS100_RLT_OPERATION_IND, and ROSE_DMS100_RLT_THIRD_PARTY conflict! */
{
ROSE_QSIG_CalledName, NULL, 1,
rose_enc_qsig_CalledName_ARG, NULL,
rose_dec_qsig_CalledName_ARG, NULL
},
{
ROSE_QSIG_ConnectedName, NULL, 2,
rose_enc_qsig_ConnectedName_ARG, NULL,
rose_dec_qsig_ConnectedName_ARG, NULL
},
{
ROSE_QSIG_BusyName, NULL, 3,
rose_enc_qsig_BusyName_ARG, NULL,
rose_dec_qsig_BusyName_ARG, NULL
},
#endif
/* *INDENT-ON* */
};
@@ -1320,19 +888,6 @@ static const struct rose_convert_msg rose_ni2_msgs[] = {
* encode_invoke_args, encode_result_args,
* decode_invoke_args, decode_result_args
*/
{
ROSE_NI2_InformationFollowing, &rose_ni2_oid, 4,
rose_enc_ni2_InformationFollowing_ARG, NULL,
rose_dec_ni2_InformationFollowing_ARG, NULL
},
/* Also used by PRI_SWITCH_ATT4ESS and PRI_SWITCH_LUCENT5E */
{
ROSE_NI2_InitiateTransfer, &rose_ni2_oid, 8,
rose_enc_ni2_InitiateTransfer_ARG, NULL,
rose_dec_ni2_InitiateTransfer_ARG, NULL
},
/* NI2 seems to have pirated several Q.SIG messages */
/*
* localValue's from Q.SIG Name-Operations
@@ -1358,6 +913,19 @@ static const struct rose_convert_msg rose_ni2_msgs[] = {
rose_enc_qsig_BusyName_ARG, NULL,
rose_dec_qsig_BusyName_ARG, NULL
},
{
ROSE_NI2_InformationFollowing, &rose_ni2_oid, 4,
rose_enc_ni2_InformationFollowing_ARG, NULL,
rose_dec_ni2_InformationFollowing_ARG, NULL
},
/* Also used by PRI_SWITCH_ATT4ESS and PRI_SWITCH_LUCENT5E */
{
ROSE_NI2_InitiateTransfer, &rose_ni2_oid, 8,
rose_enc_ni2_InitiateTransfer_ARG, NULL,
rose_dec_ni2_InitiateTransfer_ARG, NULL
},
/* *INDENT-ON* */
};
@@ -1501,40 +1069,6 @@ const char *rose_operation2str(enum rose_operation operation)
{ ROSE_ETSI_AOCECurrency, "ROSE_ETSI_AOCECurrency" },
{ ROSE_ETSI_AOCEChargingUnit, "ROSE_ETSI_AOCEChargingUnit" },
{ ROSE_ETSI_StatusRequest, "ROSE_ETSI_StatusRequest" },
{ ROSE_ETSI_CallInfoRetain, "ROSE_ETSI_CallInfoRetain" },
{ ROSE_ETSI_EraseCallLinkageID, "ROSE_ETSI_EraseCallLinkageID" },
{ ROSE_ETSI_CCBSDeactivate, "ROSE_ETSI_CCBSDeactivate" },
{ ROSE_ETSI_CCBSErase, "ROSE_ETSI_CCBSErase" },
{ ROSE_ETSI_CCBSRemoteUserFree, "ROSE_ETSI_CCBSRemoteUserFree" },
{ ROSE_ETSI_CCBSCall, "ROSE_ETSI_CCBSCall" },
{ ROSE_ETSI_CCBSStatusRequest, "ROSE_ETSI_CCBSStatusRequest" },
{ ROSE_ETSI_CCBSBFree, "ROSE_ETSI_CCBSBFree" },
{ ROSE_ETSI_CCBSStopAlerting, "ROSE_ETSI_CCBSStopAlerting" },
{ ROSE_ETSI_CCBSRequest, "ROSE_ETSI_CCBSRequest" },
{ ROSE_ETSI_CCBSInterrogate, "ROSE_ETSI_CCBSInterrogate" },
{ ROSE_ETSI_CCNRRequest, "ROSE_ETSI_CCNRRequest" },
{ ROSE_ETSI_CCNRInterrogate, "ROSE_ETSI_CCNRInterrogate" },
{ ROSE_ETSI_CCBS_T_Call, "ROSE_ETSI_CCBS_T_Call" },
{ ROSE_ETSI_CCBS_T_Suspend, "ROSE_ETSI_CCBS_T_Suspend" },
{ ROSE_ETSI_CCBS_T_Resume, "ROSE_ETSI_CCBS_T_Resume" },
{ ROSE_ETSI_CCBS_T_RemoteUserFree, "ROSE_ETSI_CCBS_T_RemoteUserFree" },
{ ROSE_ETSI_CCBS_T_Available, "ROSE_ETSI_CCBS_T_Available" },
{ ROSE_ETSI_CCBS_T_Request, "ROSE_ETSI_CCBS_T_Request" },
{ ROSE_ETSI_CCNR_T_Request, "ROSE_ETSI_CCNR_T_Request" },
{ ROSE_ETSI_MCIDRequest, "ROSE_ETSI_MCIDRequest" },
{ ROSE_ETSI_MWIActivate, "ROSE_ETSI_MWIActivate" },
{ ROSE_ETSI_MWIDeactivate, "ROSE_ETSI_MWIDeactivate" },
{ ROSE_ETSI_MWIIndicate, "ROSE_ETSI_MWIIndicate" },
{ ROSE_QSIG_CallingName, "ROSE_QSIG_CallingName" },
{ ROSE_QSIG_CalledName, "ROSE_QSIG_CalledName" },
{ ROSE_QSIG_ConnectedName, "ROSE_QSIG_ConnectedName" },
@@ -1569,15 +1103,6 @@ const char *rose_operation2str(enum rose_operation operation)
{ ROSE_QSIG_DivertingLegInformation3, "ROSE_QSIG_DivertingLegInformation3" },
{ ROSE_QSIG_CfnrDivertedLegFailed, "ROSE_QSIG_CfnrDivertedLegFailed" },
{ ROSE_QSIG_CcbsRequest, "ROSE_QSIG_CcbsRequest" },
{ ROSE_QSIG_CcnrRequest, "ROSE_QSIG_CcnrRequest" },
{ ROSE_QSIG_CcCancel, "ROSE_QSIG_CcCancel" },
{ ROSE_QSIG_CcExecPossible, "ROSE_QSIG_CcExecPossible" },
{ ROSE_QSIG_CcPathReserve, "ROSE_QSIG_CcPathReserve" },
{ ROSE_QSIG_CcRingout, "ROSE_QSIG_CcRingout" },
{ ROSE_QSIG_CcSuspend, "ROSE_QSIG_CcSuspend" },
{ ROSE_QSIG_CcResume, "ROSE_QSIG_CcResume" },
{ ROSE_QSIG_MWIActivate, "ROSE_QSIG_MWIActivate" },
{ ROSE_QSIG_MWIDeactivate, "ROSE_QSIG_MWIDeactivate" },
{ ROSE_QSIG_MWIInterrogate, "ROSE_QSIG_MWIInterrogate" },
@@ -1636,26 +1161,6 @@ const char *rose_error2str(enum rose_error_code code)
{ ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork, "ECT: Link ID Not Assigned By Network" },
{ ROSE_ERROR_CCBS_InvalidCallLinkageID, "CCBS: Invalid Call Linkage ID" },
{ ROSE_ERROR_CCBS_InvalidCCBSReference, "CCBS: Invalid CCBS Reference" },
{ ROSE_ERROR_CCBS_LongTermDenial, "CCBS: Long Term Denial" },
{ ROSE_ERROR_CCBS_ShortTermDenial, "CCBS: Short Term Denial" },
{ ROSE_ERROR_CCBS_IsAlreadyActivated, "CCBS: Is Already Activated" },
{ ROSE_ERROR_CCBS_AlreadyAccepted, "CCBS: Already Accepted" },
{ ROSE_ERROR_CCBS_OutgoingCCBSQueueFull, "CCBS: Outgoing CCBS Queue Full" },
{ ROSE_ERROR_CCBS_CallFailureReasonNotBusy, "CCBS: Call Failure Reason Not Busy" },
{ ROSE_ERROR_CCBS_NotReadyForCall, "CCBS: Not Ready For Call" },
{ ROSE_ERROR_CCBS_T_LongTermDenial, "CCBS-T: Long Term Denial" },
{ ROSE_ERROR_CCBS_T_ShortTermDenial, "CCBS-T: Short Term Denial" },
{ ROSE_ERROR_MWI_InvalidReceivingUserNr, "MWI: Invalid Receiving User Number" },
{ ROSE_ERROR_MWI_ReceivingUserNotSubscribed, "MWI: Receiving User Not Subscribed" },
{ ROSE_ERROR_MWI_ControllingUserNotRegistered,"MWI: Controlling User Not Registered" },
{ ROSE_ERROR_MWI_IndicationNotDelivered, "MWI: Indication Not Delivered" },
{ ROSE_ERROR_MWI_MaxNumOfControllingUsersReached,"MWI: Max Num Of Controlling Users Reached" },
{ ROSE_ERROR_MWI_MaxNumOfActiveInstancesReached,"MWI: Max Num Of Active Instances Reached" },
/* Q.SIG specific errors */
{ ROSE_ERROR_QSIG_Unspecified, "Unspecified" },
@@ -1668,12 +1173,6 @@ const char *rose_error2str(enum rose_error_code code)
{ ROSE_ERROR_QSIG_Div_TemporarilyUnavailable, "Diversion: Temporarily Unavailable" },
{ ROSE_ERROR_QSIG_Div_NotAuthorized, "Diversion: Not Authorized" },
{ ROSE_ERROR_QSIG_ShortTermRejection, "CC: Short Term Rejection" },
{ ROSE_ERROR_QSIG_LongTermRejection, "CC: Long Term Rejection" },
{ ROSE_ERROR_QSIG_RemoteUserBusyAgain, "CC: Remote User Busy Again" },
{ ROSE_ERROR_QSIG_FailureToMatch, "CC: Failure To Match" },
{ ROSE_ERROR_QSIG_FailedDueToInterworking, "CC: Failed Due To Interworking" },
{ ROSE_ERROR_QSIG_InvalidMsgCentreId, "MWI: Invalid Message Center ID" },
/* DMS-100 specific errors */
@@ -2742,6 +2241,13 @@ const unsigned char *rose_decode(struct pri *ctrl, const unsigned char *pos,
return NULL;
}
if (pos < end) {
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " %u byte(s) of trailing data not consumed.\n",
(unsigned) (end - pos));
}
}
return pos;
}

856
rose.h
View File

@@ -103,45 +103,6 @@ enum rose_operation {
ROSE_ETSI_EctInform, /*!< Invoke only */
ROSE_ETSI_EctLoopTest, /*!< Invoke/Result */
/* ETSI Status-Request-Procedure */
ROSE_ETSI_StatusRequest, /*!< Invoke/Result */
/* ETSI CCBS-Operations-and-Errors */
ROSE_ETSI_CallInfoRetain, /*!< Invoke only */
ROSE_ETSI_CCBSRequest, /*!< Invoke/Result */
ROSE_ETSI_CCBSDeactivate, /*!< Invoke/Result */
ROSE_ETSI_CCBSInterrogate, /*!< Invoke/Result */
ROSE_ETSI_CCBSErase, /*!< Invoke only */
ROSE_ETSI_CCBSRemoteUserFree, /*!< Invoke only */
ROSE_ETSI_CCBSCall, /*!< Invoke only */
ROSE_ETSI_CCBSStatusRequest, /*!< Invoke/Result */
ROSE_ETSI_CCBSBFree, /*!< Invoke only */
ROSE_ETSI_EraseCallLinkageID, /*!< Invoke only */
ROSE_ETSI_CCBSStopAlerting, /*!< Invoke only */
/* ETSI CCBS-private-networks-Operations-and-Errors */
ROSE_ETSI_CCBS_T_Request, /*!< Invoke/Result */
ROSE_ETSI_CCBS_T_Call, /*!< Invoke only */
ROSE_ETSI_CCBS_T_Suspend, /*!< Invoke only */
ROSE_ETSI_CCBS_T_Resume, /*!< Invoke only */
ROSE_ETSI_CCBS_T_RemoteUserFree, /*!< Invoke only */
ROSE_ETSI_CCBS_T_Available, /*!< Invoke only */
/* ETSI CCNR-Operations-and-Errors */
ROSE_ETSI_CCNRRequest, /*!< Invoke/Result */
ROSE_ETSI_CCNRInterrogate, /*!< Invoke/Result */
/* ETSI CCNR-private-networks-Operations-and-Errors */
ROSE_ETSI_CCNR_T_Request, /*!< Invoke/Result */
/* ETSI MCID-Operations */
ROSE_ETSI_MCIDRequest, /*!< Invoke/Result */
/* ETSI MWI-Operations-and-Errors */
ROSE_ETSI_MWIActivate, /*!< Invoke/Result */
ROSE_ETSI_MWIDeactivate, /*!< Invoke/Result */
ROSE_ETSI_MWIIndicate, /*!< Invoke only */
/* Q.SIG Name-Operations */
ROSE_QSIG_CallingName, /*!< Invoke only */
ROSE_QSIG_CalledName, /*!< Invoke only */
@@ -180,16 +141,6 @@ enum rose_operation {
ROSE_QSIG_DivertingLegInformation3, /*!< Invoke only */
ROSE_QSIG_CfnrDivertedLegFailed, /*!< Invoke only */
/* Q.SIG SS-CC-Operations */
ROSE_QSIG_CcbsRequest, /*!< Invoke/Result */
ROSE_QSIG_CcnrRequest, /*!< Invoke/Result */
ROSE_QSIG_CcCancel, /*!< Invoke only */
ROSE_QSIG_CcExecPossible, /*!< Invoke only */
ROSE_QSIG_CcPathReserve, /*!< Invoke/Result */
ROSE_QSIG_CcRingout, /*!< Invoke only */
ROSE_QSIG_CcSuspend, /*!< Invoke only */
ROSE_QSIG_CcResume, /*!< Invoke only */
/* Q.SIG SS-MWI-Operations */
ROSE_QSIG_MWIActivate, /*!< Invoke/Result */
ROSE_QSIG_MWIDeactivate, /*!< Invoke/Result */
@@ -247,29 +198,6 @@ enum rose_error_code {
/* ETSI Explicit-Call-Transfer-Operations-and-Errors */
ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork,
/* ETSI CCBS-Operations-and-Errors */
ROSE_ERROR_CCBS_InvalidCallLinkageID,
ROSE_ERROR_CCBS_InvalidCCBSReference,
ROSE_ERROR_CCBS_LongTermDenial,
ROSE_ERROR_CCBS_ShortTermDenial,
ROSE_ERROR_CCBS_IsAlreadyActivated,
ROSE_ERROR_CCBS_AlreadyAccepted,
ROSE_ERROR_CCBS_OutgoingCCBSQueueFull,
ROSE_ERROR_CCBS_CallFailureReasonNotBusy,
ROSE_ERROR_CCBS_NotReadyForCall,
/* ETSI CCBS-private-networks-Operations-and-Errors */
ROSE_ERROR_CCBS_T_LongTermDenial,
ROSE_ERROR_CCBS_T_ShortTermDenial,
/* ETSI MWI-Operations-and-Errors */
ROSE_ERROR_MWI_InvalidReceivingUserNr,
ROSE_ERROR_MWI_ReceivingUserNotSubscribed,
ROSE_ERROR_MWI_ControllingUserNotRegistered,
ROSE_ERROR_MWI_IndicationNotDelivered,
ROSE_ERROR_MWI_MaxNumOfControllingUsersReached,
ROSE_ERROR_MWI_MaxNumOfActiveInstancesReached,
/* Q.SIG from various specifications */
ROSE_ERROR_QSIG_Unspecified,
@@ -285,13 +213,6 @@ enum rose_error_code {
ROSE_ERROR_QSIG_Div_TemporarilyUnavailable,
ROSE_ERROR_QSIG_Div_NotAuthorized,
/* Q.SIG SS-CC-Operations */
ROSE_ERROR_QSIG_ShortTermRejection,
ROSE_ERROR_QSIG_LongTermRejection,
ROSE_ERROR_QSIG_RemoteUserBusyAgain,
ROSE_ERROR_QSIG_FailureToMatch,
ROSE_ERROR_QSIG_FailedDueToInterworking,
/* Q.SIG SS-MWI-Operations */
ROSE_ERROR_QSIG_InvalidMsgCentreId,
@@ -403,31 +324,6 @@ enum {
/* ------------------------------------------------------------------- */
/*
* Comment obtained from ECMA-242 ASN.1 source.
* a VisibleString containing:
* - the (local) date in 8 digits (YYYYMMDD),
* - followed by (local) time of day in 4 or 6 digits (HHMM[SS]),
* - optionally followed by the letter "Z" or
* by a local time differential in 5 digits ("+"HHMM or "-"HHMM);
* this date and time representation follows ISO 8601
* Examples:
* 1) 19970621194530, meaning 21 June 1997, 19:45:30;
* 2) 19970621194530Z, meaning the same as 1);
* 3) 19970621194530-0500, meaning the same as 1),
* 5 hours retarded in relation to UTC time
*
* GeneralizedTime ::= [UNIVERSAL 24] IMPLICIT VisibleString
*/
struct roseGeneralizedTime {
/*! GeneralizedTime (SIZE (12..19)) */
unsigned char str[19 + 1];
};
/* ------------------------------------------------------------------- */
/*
* PartyNumber ::= CHOICE {
* -- the numbering plan is the default numbering plan of
@@ -1775,551 +1671,6 @@ struct roseEtsiEctLoopTest_RES {
/* ------------------------------------------------------------------- */
/*
* ARGUMENT SEQUENCE {
* compatibilityMode CompatibilityMode,
*
* -- The BC, HLC (optional) and LLC (optional) information
* -- elements shall be embedded in q931InfoElement
* q931InformationElement Q931InformationElement
* }
*/
struct roseEtsiStatusRequest_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \details allBasicServices(0), oneOrMoreBasicServices(1) */
u_int8_t compatibility_mode;
};
/*
* RESULT StatusResult
*/
struct roseEtsiStatusRequest_RES {
/*! \details compatibleAndFree(0), compatibleAndBusy(1), incompatible(2) */
u_int8_t status;
};
/* ------------------------------------------------------------------- */
/*
* CallLinkageID ::= INTEGER (0..127)
* CCBSReference ::= INTEGER (0..127)
*/
/*
* ARGUMENT callLinkageID CallLinkageID
*/
struct roseEtsiCallInfoRetain_ARG {
/*! \brief Call Linkage Record ID */
u_int8_t call_linkage_id;
};
/*
* ARGUMENT callLinkageID CallLinkageID
*/
struct roseEtsiEraseCallLinkageID_ARG {
/*! \brief Call Linkage Record ID */
u_int8_t call_linkage_id;
};
/*
* ARGUMENT callLinkageID CallLinkageID
*/
struct roseEtsiCCBSRequest_ARG {
/*! \brief Call Linkage Record ID */
u_int8_t call_linkage_id;
};
/*
* RESULT SEQUENCE {
* recallMode RecallMode,
* cCBSReference CCBSReference
* }
*/
struct roseEtsiCCBSRequest_RES {
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* ARGUMENT cCBSReference CCBSReference
*/
struct roseEtsiCCBSDeactivate_ARG {
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* ARGUMENT SEQUENCE {
* cCBSReference CCBSReference OPTIONAL,
* partyNumberOfA PartyNumber OPTIONAL
* }
*/
struct roseEtsiCCBSInterrogate_ARG {
/*! \brief Party A number (Optional) */
struct rosePartyNumber a_party_number;
/*! \brief TRUE if CCBSReference present */
u_int8_t ccbs_reference_present;
/*! \brief CCBS Record ID (optional) */
u_int8_t ccbs_reference;
};
/*
* -- The Bearer capability, High layer compatibility (optional)
* -- and Low layer compatibility (optional) information elements
* -- shall be embedded in q931InfoElement.
* CallInformation ::= SEQUENCE {
* addressOfB Address,
* q931InfoElement Q931InformationElement,
* cCBSReference CCBSReference,
* subAddressOfA PartySubaddress OPTIONAL
* }
*/
struct roseEtsiCallInformation {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief Address of B */
struct roseAddress address_of_b;
/*! \brief Subaddress of A (Optional) */
struct rosePartySubaddress subaddress_of_a;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* CallDetails ::= SEQUENCE SIZE(1..5) OF CallInformation
*/
struct roseEtsiCallDetailsList {
struct roseEtsiCallInformation list[5];
/*! \brief Number of CallDetails records present */
u_int8_t num_records;
};
/*
* RESULT SEQUENCE {
* recallMode RecallMode,
* callDetails CallDetails OPTIONAL
* }
*/
struct roseEtsiCCBSInterrogate_RES {
struct roseEtsiCallDetailsList call_details;
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
};
/*
* ARGUMENT SEQUENCE {
* recallMode RecallMode,
* cCBSReference CCBSReference,
* addressOfB Address,
* q931InfoElement Q931InformationElement,
* eraseReason CCBSEraseReason
* }
*/
struct roseEtsiCCBSErase_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief Address of B */
struct roseAddress address_of_b;
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
/*!
* \brief CCBS Erase reason
* \details
* normal-unspecified(0),
* t-CCBS2-timeout(1),
* t-CCBS3-timeout(2),
* basic-call-failed(3)
*/
u_int8_t reason;
};
/*
* ARGUMENT SEQUENCE {
* recallMode RecallMode,
* cCBSReference CCBSReference,
* addressOfB Address,
* q931InfoElement Q931InformationElement
* }
*/
struct roseEtsiCCBSRemoteUserFree_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief Address of B */
struct roseAddress address_of_b;
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* ARGUMENT cCBSReference CCBSReference
*/
struct roseEtsiCCBSCall_ARG {
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* ARGUMENT SEQUENCE {
* recallMode RecallMode,
* cCBSReference CCBSReference,
* q931InfoElement Q931InformationElement
* }
*/
struct roseEtsiCCBSStatusRequest_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* RESULT BOOLEAN -- free=TRUE, busy=FALSE
*/
struct roseEtsiCCBSStatusRequest_RES {
/*! \brief TRUE if User A is free */
u_int8_t free;
};
/*
* ARGUMENT SEQUENCE {
* recallMode RecallMode,
* cCBSReference CCBSReference,
* addressOfB Address,
* q931InfoElement Q931InformationElement
* }
*/
struct roseEtsiCCBSBFree_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief Address of B */
struct roseAddress address_of_b;
/*! \details globalRecall(0), specificRecall(1) */
u_int8_t recall_mode;
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/*
* ARGUMENT cCBSReference CCBSReference
*/
struct roseEtsiCCBSStopAlerting_ARG {
/*! \brief CCBS Record ID */
u_int8_t ccbs_reference;
};
/* ------------------------------------------------------------------- */
/*
* ARGUMENT SEQUENCE {
* destinationAddress Address,
*
* -- contains HLC, LLC and BC information
* q931InfoElement Q931InformationElement,
*
* retentionSupported [1] IMPLICIT BOOLEAN DEFAULT FALSE,
*
* -- The use of this parameter is specified in
* -- EN 300 195-1 for interaction of CCBS with CLIP
* presentationAllowedIndicator [2] IMPLICIT BOOLEAN OPTIONAL,
*
* -- The use of this parameter is specified in
* -- EN 300 195-1 for interaction of CCBS with CLIP
* originatingAddress Address OPTIONAL
* }
*/
struct roseEtsiCCBS_T_Request_ARG {
/*! \brief The BC, HLC (optional) and LLC (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief Address of B */
struct roseAddress destination;
/*! \brief Caller-ID Address (Present if Originating.Party.LengthOfNumber is nonzero) */
struct roseAddress originating;
/*! \brief TRUE if the PresentationAllowedIndicator is present */
u_int8_t presentation_allowed_indicator_present;
/*! \brief TRUE if presentation is allowed for the originating address (optional) */
u_int8_t presentation_allowed_indicator;
/*! \brief TRUE if User A's CCBS request is continued if user B is busy again. */
u_int8_t retention_supported;
};
/*
* RESULT retentionSupported BOOLEAN -- Default False
*/
struct roseEtsiCCBS_T_Request_RES {
/*! \brief TRUE if User A's CCBS request is continued if user B is busy again. */
u_int8_t retention_supported;
};
/* ------------------------------------------------------------------- */
/*
* MessageID ::= SEQUENCE {
* messageRef MessageRef,
* status MessageStatus
* }
*/
struct roseEtsiMessageID {
/*! \brief Message reference number. (INTEGER (0..65535)) */
u_int16_t reference_number;
/*!
* \brief Message status
* \details
* added_message(0),
* removed_message(1)
*/
u_int8_t status;
};
/*
* ARGUMENT SEQUENCE {
* receivingUserNr PartyNumber,
* basicService BasicService,
* controllingUserNr [1] EXPLICIT PartyNumber OPTIONAL,
* numberOfMessages [2] EXPLICIT MessageCounter OPTIONAL,
* controllingUserProvidedNr [3] EXPLICIT PartyNumber OPTIONAL,
* time [4] EXPLICIT GeneralizedTime OPTIONAL,
* messageId [5] EXPLICIT MessageID OPTIONAL,
* mode [6] EXPLICIT InvocationMode OPTIONAL
* }
*/
struct roseEtsiMWIActivate_ARG {
/*! \brief Number of messages in mailbox. (INTEGER (0..65535)) (Optional) */
u_int16_t number_of_messages;
/*! \brief Message ID (Status of this message) (Optional)*/
struct roseEtsiMessageID message_id;
/*! \brief Receiving user number (Who the message is for.) */
struct rosePartyNumber receiving_user_number;
/*! \brief Controlling user number (Mailbox number) (Optional) */
struct rosePartyNumber controlling_user_number;
/*! \brief Controlling user provided number (Caller-ID of party leaving message) (Optional) */
struct rosePartyNumber controlling_user_provided_number;
/*! \brief When message left. (optional) */
struct roseGeneralizedTime time;
/*!
* \brief Type of call leaving message.
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
/*!
* \brief Invocation mode (When it should be delivered.) (Optional)
* \details
* deferred(0),
* immediate(1),
* combined(2)
*/
u_int8_t mode;
/*! \brief TRUE if NumberOfMessages present */
u_int8_t number_of_messages_present;
/*! \brief TRUE if time present */
u_int8_t time_present;
/*! \brief TRUE if MessageId present */
u_int8_t message_id_present;
/*! \brief TRUE if invocation mode present */
u_int8_t mode_present;
};
/*
* ARGUMENT SEQUENCE {
* receivingUserNr PartyNumber,
* basicService BasicService,
* controllingUserNr PartyNumber OPTIONAL,
* mode InvocationMode OPTIONAL
* }
*/
struct roseEtsiMWIDeactivate_ARG {
/*! \brief Receiving user number (Who the message is for.) */
struct rosePartyNumber receiving_user_number;
/*! \brief Controlling user number (Mailbox number) (Optional) */
struct rosePartyNumber controlling_user_number;
/*!
* \brief Type of call leaving message.
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
/*!
* \brief Invocation mode (When it should be delivered.) (Optional)
* \details
* deferred(0),
* immediate(1),
* combined(2)
*/
u_int8_t mode;
/*! \brief TRUE if invocation mode present */
u_int8_t mode_present;
};
/*
* ARGUMENT SEQUENCE {
* controllingUserNr [1] EXPLICIT PartyNumber OPTIONAL,
* basicService [2] EXPLICIT BasicService OPTIONAL,
* numberOfMessages [3] EXPLICIT MessageCounter OPTIONAL,
* controllingUserProvidedNr [4] EXPLICIT PartyNumber OPTIONAL,
* time [5] EXPLICIT GeneralizedTime OPTIONAL,
* messageId [6] EXPLICIT MessageID OPTIONAL
* }
*/
struct roseEtsiMWIIndicate_ARG {
/*! \brief Number of messages in mailbox. (INTEGER (0..65535)) (Optional) */
u_int16_t number_of_messages;
/*! \brief Message ID (Status of this message) (Optional)*/
struct roseEtsiMessageID message_id;
/*! \brief Controlling user number (Mailbox number) (Optional) */
struct rosePartyNumber controlling_user_number;
/*! \brief Controlling user provided number (Caller-ID of party leaving message) (Optional) */
struct rosePartyNumber controlling_user_provided_number;
/*! \brief When message left. (optional) */
struct roseGeneralizedTime time;
/*!
* \brief Type of call leaving message.
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
/*! \brief TRUE if basic_service present */
u_int8_t basic_service_present;
/*! \brief TRUE if NumberOfMessages present */
u_int8_t number_of_messages_present;
/*! \brief TRUE if time present */
u_int8_t time_present;
/*! \brief TRUE if MessageId present */
u_int8_t message_id_present;
};
/* ------------------------------------------------------------------- */
/*
* Name ::= CHOICE {
* -- iso8859-1 is implied in namePresentationAllowedSimple.
@@ -3484,146 +2835,6 @@ struct roseQsigDivertingLegInformation3_ARG {
/* ------------------------------------------------------------------- */
/*
* CcExtension ::= CHOICE {
* none NULL,
* single [14] IMPLICIT Extension,
* multiple [15] IMPLICIT SEQUENCE OF Extension
* }
*/
/*
* CcRequestArg ::= SEQUENCE {
* numberA PresentedNumberUnscreened,
* numberB PartyNumber,
*
* -- permitted information elements are:
* -- Bearer capability;
* -- Low layer compatibility;
* -- High layer compatibility
* service PSS1InformationElement,
* subaddrA [10] EXPLICIT PartySubaddress OPTIONAL,
* subaddrB [11] EXPLICIT PartySubaddress OPTIONAL,
* can-retain-service [12] IMPLICIT BOOLEAN DEFAULT FALSE,
*
* -- TRUE: signalling connection to be retained;
* -- FALSE: signalling connection to be released;
* -- omission: release or retain signalling connection
* retain-sig-connection [13] IMPLICIT BOOLEAN OPTIONAL,
* extension CcExtension OPTIONAL
* }
*/
struct roseQsigCcRequestArg {
struct rosePresentedNumberUnscreened number_a;
struct rosePartyNumber number_b;
/*!
* \brief subaddrA (optional)
* The subaddress is present if the length is nonzero.
*/
struct rosePartySubaddress subaddr_a;
/*!
* \brief subaddrB (optional)
* The subaddress is present if the length is nonzero.
*/
struct rosePartySubaddress subaddr_b;
/*!
* \brief The BC, HLC (optional) and LLC (optional) information.
* \note The ASN.1 field name is service.
*/
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
/*! \brief TRUE if can retain service (DEFAULT FALSE) */
u_int8_t can_retain_service;
/*!
* \brief TRUE if retain_sig_connection present
* \note If not present then the signaling connection could be
* released or retained.
*/
u_int8_t retain_sig_connection_present;
/*!
* \brief Determine if the signalling connection should be retained.
* \note TRUE if signalling connection to be retained.
* \note FALSE if signalling connection to be released.
*/
u_int8_t retain_sig_connection;
};
/*
* CcRequestRes ::= SEQUENCE {
* no-path-reservation [0] IMPLICIT BOOLEAN DEFAULT FALSE,
* retain-service [1] IMPLICIT BOOLEAN DEFAULT FALSE,
* extension CcExtension OPTIONAL
* }
*/
struct roseQsigCcRequestRes {
/*! \brief TRUE if no path reservation. (DEFAULT FALSE) */
u_int8_t no_path_reservation;
/*! \brief TRUE if agree to retain service (DEFAULT FALSE) */
u_int8_t retain_service;
};
/*
* CcOptionalArg ::= CHOICE {
* fullArg [0] IMPLICIT SEQUENCE {
* numberA PartyNumber,
* numberB PartyNumber,
*
* -- permitted information elements are:
* -- Bearer capability;
* -- Low layer compatibility;
* -- High layer compatibility.
* service PSS1InformationElement,
* subaddrA [10] EXPLICIT PartySubaddress OPTIONAL,
* subaddrB [11] EXPLICIT PartySubaddress OPTIONAL,
* extension CcExtension OPTIONAL
* },
* extArg CcExtension
* }
*/
struct roseQsigCcOptionalArg {
#if 1 /* The conditional is here to indicate fullArg values grouping. */
struct rosePartyNumber number_a;
struct rosePartyNumber number_b;
/*!
* \brief subaddrA (optional)
* The subaddress is present if the length is nonzero.
*/
struct rosePartySubaddress subaddr_a;
/*!
* \brief subaddrB (optional)
* The subaddress is present if the length is nonzero.
*/
struct rosePartySubaddress subaddr_b;
/*!
* \brief The BC, HLC (optional) and LLC (optional) information.
* \note The ASN.1 field name is service.
*/
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + 1];
#endif /* end fullArg values */
/*! \brief TRUE if the fullArg values are present. */
u_int8_t full_arg_present;
};
/* ------------------------------------------------------------------- */
/*
* MsgCentreId ::= CHOICE {
* integer [0] IMPLICIT INTEGER (0..65535),
@@ -3688,7 +2899,7 @@ struct roseQsigMWIActivateArg {
struct rosePartyNumber originating_number;
/*! \brief GeneralizedTime (SIZE (12..19)) (optional) */
struct roseGeneralizedTime timestamp;
unsigned char timestamp[19 + 1];
/*!
* \details
@@ -3913,7 +3124,7 @@ struct roseQsigMWIInterrogateResElt {
struct rosePartyNumber originating_number;
/*! \brief GeneralizedTime (SIZE (12..19)) (optional) */
struct roseGeneralizedTime timestamp;
unsigned char timestamp[19 + 1];
/*!
* \details
@@ -4072,39 +3283,6 @@ union rose_msg_invoke_etsi_args {
struct roseEtsiSubaddressTransfer_ARG SubaddressTransfer;
struct roseEtsiEctInform_ARG EctInform;
struct roseEtsiEctLoopTest_ARG EctLoopTest;
/* ETSI Status Request (CCBS/CCNR support) */
struct roseEtsiStatusRequest_ARG StatusRequest;
/* ETSI CCBS/CCNR support */
struct roseEtsiCallInfoRetain_ARG CallInfoRetain;
struct roseEtsiEraseCallLinkageID_ARG EraseCallLinkageID;
struct roseEtsiCCBSDeactivate_ARG CCBSDeactivate;
struct roseEtsiCCBSErase_ARG CCBSErase;
struct roseEtsiCCBSRemoteUserFree_ARG CCBSRemoteUserFree;
struct roseEtsiCCBSCall_ARG CCBSCall;
struct roseEtsiCCBSStatusRequest_ARG CCBSStatusRequest;
struct roseEtsiCCBSBFree_ARG CCBSBFree;
struct roseEtsiCCBSStopAlerting_ARG CCBSStopAlerting;
/* ETSI CCBS */
struct roseEtsiCCBSRequest_ARG CCBSRequest;
struct roseEtsiCCBSInterrogate_ARG CCBSInterrogate;
/* ETSI CCNR */
struct roseEtsiCCBSRequest_ARG CCNRRequest;
struct roseEtsiCCBSInterrogate_ARG CCNRInterrogate;
/* ETSI CCBS-T */
struct roseEtsiCCBS_T_Request_ARG CCBS_T_Request;
/* ETSI CCNR-T */
struct roseEtsiCCBS_T_Request_ARG CCNR_T_Request;
/* ETSI Message Waiting Indication (MWI) */
struct roseEtsiMWIActivate_ARG MWIActivate;
struct roseEtsiMWIDeactivate_ARG MWIDeactivate;
struct roseEtsiMWIIndicate_ARG MWIIndicate;
};
/*! \brief Facility ie result etsi messages with arguments. */
@@ -4119,26 +3297,6 @@ union rose_msg_result_etsi_args {
/* ETSI Explicit Call Transfer (ECT) */
struct roseEtsiEctLinkIdRequest_RES EctLinkIdRequest;
struct roseEtsiEctLoopTest_RES EctLoopTest;
/* ETSI Status Request (CCBS/CCNR support) */
struct roseEtsiStatusRequest_RES StatusRequest;
/* ETSI CCBS/CCNR support */
struct roseEtsiCCBSStatusRequest_RES CCBSStatusRequest;
/* ETSI CCBS */
struct roseEtsiCCBSRequest_RES CCBSRequest;
struct roseEtsiCCBSInterrogate_RES CCBSInterrogate;
/* ETSI CCNR */
struct roseEtsiCCBSRequest_RES CCNRRequest;
struct roseEtsiCCBSInterrogate_RES CCNRInterrogate;
/* ETSI CCBS-T */
struct roseEtsiCCBS_T_Request_RES CCBS_T_Request;
/* ETSI CCNR-T */
struct roseEtsiCCBS_T_Request_RES CCNR_T_Request;
};
/*! \brief Facility ie invoke qsig messages with arguments. */
@@ -4175,12 +3333,6 @@ union rose_msg_invoke_qsig_args {
struct roseQsigDivertingLegInformation2_ARG DivertingLegInformation2;
struct roseQsigDivertingLegInformation3_ARG DivertingLegInformation3;
/* Q.SIG SS-CC-Operations */
struct roseQsigCcRequestArg CcbsRequest;
struct roseQsigCcRequestArg CcnrRequest;
struct roseQsigCcOptionalArg CcCancel;
struct roseQsigCcOptionalArg CcExecPossible;
/* Q.SIG SS-MWI-Operations */
struct roseQsigMWIActivateArg MWIActivate;
struct roseQsigMWIDeactivateArg MWIDeactivate;
@@ -4199,10 +3351,6 @@ union rose_msg_result_qsig_args {
/* Q.SIG Call-Diversion-Operations */
struct roseQsigForwardingList InterrogateDiversionQ;
/* Q.SIG SS-CC-Operations */
struct roseQsigCcRequestRes CcbsRequest;
struct roseQsigCcRequestRes CcnrRequest;
/* Q.SIG SS-MWI-Operations */
struct roseQsigMWIInterrogateRes MWIInterrogate;
};

View File

@@ -623,13 +623,8 @@ unsigned char *rose_enc_etsi_AOCSCurrency_ARG(struct pri *ctrl, unsigned char *p
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
break;
case 1: /* currency_info_list */
if (args->etsi.AOCSCurrency.currency_info.num_records) {
ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
ASN1_TAG_SEQUENCE, &args->etsi.AOCSCurrency.currency_info));
} else {
/* There were no records so encode as charge_not_available */
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
}
ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
ASN1_TAG_SEQUENCE, &args->etsi.AOCSCurrency.currency_info));
break;
default:
ASN1_ENC_ERROR(ctrl, "Unknown AOCSCurrency type");

File diff suppressed because it is too large Load Diff

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

@@ -238,153 +238,6 @@ const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned ta
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);
@@ -563,64 +416,6 @@ const unsigned char *rose_dec_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsi
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);

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

@@ -126,7 +126,7 @@ unsigned char *rose_enc_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned char *po
}
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));
mwi_activate->timestamp, sizeof(mwi_activate->timestamp) - 1));
}
if (mwi_activate->priority_present) {
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5,
@@ -254,7 +254,7 @@ static unsigned char *rose_enc_qsig_MWIInterrogateResElt(struct pri *ctrl,
}
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));
record->timestamp, sizeof(record->timestamp) - 1));
}
if (record->priority_present) {
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5,
@@ -450,8 +450,7 @@ const unsigned char *rose_dec_qsig_MWIActivate_ARG(struct pri *ctrl, unsigned ta
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));
sizeof(mwi_activate->timestamp), mwi_activate->timestamp, &str_len));
mwi_activate->timestamp_present = 1;
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
@@ -711,7 +710,7 @@ static const unsigned char *rose_dec_qsig_MWIInterrogateResElt(struct pri *ctrl,
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));
sizeof(record->timestamp), record->timestamp, &str_len));
record->timestamp_present = 1;
break;
case ASN1_CLASS_CONTEXT_SPECIFIC | 5:

View File

@@ -382,7 +382,6 @@ static const unsigned char *rose_dec_qsig_PartyName_ARG_Backend(struct pri *ctrl
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));

File diff suppressed because it is too large Load Diff

View File

@@ -48,10 +48,13 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <zaptel/zaptel.h>
#ifndef SOLARIS
#include <zap.h>
#endif
#include <pthread.h>
#include <sys/select.h>
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"
#ifndef AF_LOCAL
@@ -63,7 +66,7 @@
#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;
@@ -156,9 +159,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);
@@ -182,9 +185,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,7 +207,7 @@ 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(;;) {
@@ -225,6 +228,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) {
@@ -234,9 +238,9 @@ static void *dchan(void *data)
}
if (e) {
if (first == pri) {
event1(pri, e);
event1(e->gen.pri, e);
} else {
event2(pri, e);
event2(e->gen.pri, e);
}
}
pthread_mutex_unlock(&lock);