Compare commits
92 Commits
1.4.12-bet
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ace221ca0 | ||
|
|
a7a2245b12 | ||
|
|
c038af7892 | ||
|
|
f8e6096bfe | ||
|
|
d2585d6da2 | ||
|
|
90019b935a | ||
|
|
c71499df29 | ||
|
|
2952e95715 | ||
|
|
7da3366cec | ||
|
|
734e922301 | ||
|
|
a9722804c1 | ||
|
|
6b2cc87b30 | ||
|
|
fc96191788 | ||
|
|
5fda3d8c68 | ||
|
|
af8a550ff9 | ||
|
|
a50516c1e4 | ||
|
|
998e6ba598 | ||
|
|
cfac266390 | ||
|
|
13beaacc80 | ||
|
|
84b2560da5 | ||
|
|
28553ff8cb | ||
|
|
1a0927ca23 | ||
|
|
de78c8d37f | ||
|
|
cdb844c16b | ||
|
|
75bf8f0a20 | ||
|
|
5e3581c977 | ||
|
|
d9c6cc68a5 | ||
|
|
27808e3640 | ||
|
|
4af121db62 | ||
|
|
053a38202e | ||
|
|
fffb7babaf | ||
|
|
f78400fc07 | ||
|
|
a7eaec1aaa | ||
|
|
17649b363b | ||
|
|
2c159d4685 | ||
|
|
6078b21698 | ||
|
|
4e7c3d1462 | ||
|
|
5947536965 | ||
|
|
c5ec479bd2 | ||
|
|
092811da55 | ||
|
|
239f8186ef | ||
|
|
c794af652e | ||
|
|
1013e7626d | ||
|
|
afd91f7f31 | ||
|
|
a5efd98835 | ||
|
|
898bc57fce | ||
|
|
9effbfc130 | ||
|
|
e7a5d0da62 | ||
|
|
df22f0e1cb | ||
|
|
492a19ab7d | ||
|
|
2867fc717e | ||
|
|
d1cac6352a | ||
|
|
e01dce27b7 | ||
|
|
ed0d76d538 | ||
|
|
d0dbd5b3f2 | ||
|
|
82a0a8e2ab | ||
|
|
261ab22dda | ||
|
|
1b32a0e31b | ||
|
|
19e2a84c89 | ||
|
|
4faa2935f8 | ||
|
|
8dc9486287 | ||
|
|
cea6d541df | ||
|
|
b79b886fc4 | ||
|
|
517e5ac5ce | ||
|
|
12805eb71f | ||
|
|
d2984ee7eb | ||
|
|
230e2d9013 | ||
|
|
de0bf0b50e | ||
|
|
f7866a2de8 | ||
|
|
8db67a915d | ||
|
|
948625318a | ||
|
|
69694554fb | ||
|
|
33aafe9b5a | ||
|
|
7f55b600e0 | ||
|
|
5923df047d | ||
|
|
f9c3c8d026 | ||
|
|
53c142990f | ||
|
|
cd588eccce | ||
|
|
cf456d41e2 | ||
|
|
31b4b63b40 | ||
|
|
fb61cedfd7 | ||
|
|
2045db6a69 | ||
|
|
21638280af | ||
|
|
ae11fcd0e6 | ||
|
|
384ae1e688 | ||
|
|
05158ec5fb | ||
|
|
0c79b0a4b1 | ||
|
|
e0f4da2773 | ||
|
|
c20f34992a | ||
|
|
ad998f6f64 | ||
|
|
4011816ead | ||
|
|
34370a5984 |
1
.cleancount
Normal file
1
.cleancount
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
*.o
|
||||
*.o.d
|
||||
*.lo
|
||||
*.so
|
||||
*.a
|
||||
libpri.so.*
|
||||
pridump
|
||||
pritest
|
||||
rosetest
|
||||
testprilib
|
||||
version.c
|
||||
|
||||
4
.gitreview
Normal file
4
.gitreview
Normal file
@@ -0,0 +1,4 @@
|
||||
[gerrit]
|
||||
host=gerrit.asterisk.org
|
||||
port=29418
|
||||
project=libpri.git
|
||||
108
Makefile
108
Makefile
@@ -10,26 +10,25 @@
|
||||
# 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)
|
||||
@@ -68,37 +67,24 @@ STATIC_OBJS= \
|
||||
rose_qsig_name.o \
|
||||
version.o
|
||||
DYNAMIC_OBJS= \
|
||||
copy_string.lo \
|
||||
pri.lo \
|
||||
q921.lo \
|
||||
prisched.lo \
|
||||
q931.lo \
|
||||
pri_aoc.lo \
|
||||
pri_cc.lo \
|
||||
pri_facility.lo \
|
||||
asn1_primitive.lo \
|
||||
rose.lo \
|
||||
rose_address.lo \
|
||||
rose_etsi_aoc.lo \
|
||||
rose_etsi_cc.lo \
|
||||
rose_etsi_diversion.lo \
|
||||
rose_etsi_ect.lo \
|
||||
rose_etsi_mwi.lo \
|
||||
rose_other.lo \
|
||||
rose_q931.lo \
|
||||
rose_qsig_aoc.lo \
|
||||
rose_qsig_cc.lo \
|
||||
rose_qsig_ct.lo \
|
||||
rose_qsig_diversion.lo \
|
||||
rose_qsig_mwi.lo \
|
||||
rose_qsig_name.lo \
|
||||
version.lo
|
||||
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS) $(LIBPRI_OPT)
|
||||
$(STATIC_OBJS)
|
||||
CFLAGS ?= -g
|
||||
CFLAGS += $(CPPFLAGS)
|
||||
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
|
||||
INSTALL_PREFIX=$(DESTDIR)
|
||||
INSTALL_BASE=/usr
|
||||
libdir?=$(INSTALL_BASE)/lib
|
||||
SOFLAGS:=-Wl,-h$(DYNAMIC_LIBRARY)
|
||||
LDCONFIG = /sbin/ldconfig
|
||||
ifneq ($(findstring Darwin,$(OSARCH)),)
|
||||
SOFLAGS=$(LDFLAGS) -dynamic -bundle -Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace
|
||||
ifeq ($(shell /usr/bin/sw_vers -productVersion | cut -c1-4),10.6)
|
||||
SOFLAGS+=/usr/lib/bundle1.o
|
||||
endif
|
||||
LDCONFIG=/usr/bin/true
|
||||
else
|
||||
SOFLAGS=$(LDFLAGS) -shared -Wl,-h$(DYNAMIC_LIBRARY) $(COVERAGE_LDFLAGS)
|
||||
LDCONFIG = /sbin/ldconfig
|
||||
endif
|
||||
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX XGNUX))
|
||||
LDCONFIG_FLAGS=-n
|
||||
else
|
||||
@@ -110,11 +96,13 @@ 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 .)
|
||||
@@ -126,7 +114,13 @@ ifeq ($(PROC),sparc64)
|
||||
PROC=ultrasparc
|
||||
LIBPRI_OPT = -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
|
||||
else
|
||||
LIBPRI_OPT = -O2
|
||||
ifneq ($(CODE_COVERAGE),)
|
||||
LIBPRI_OPT=
|
||||
COVERAGE_CFLAGS=-ftest-coverage -fprofile-arcs
|
||||
COVERAGE_LDFLAGS=-ftest-coverage -fprofile-arcs
|
||||
else
|
||||
LIBPRI_OPT=-O2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CPUARCH),i686)
|
||||
@@ -134,7 +128,7 @@ CFLAGS += -m32
|
||||
SOFLAGS += -m32
|
||||
endif
|
||||
|
||||
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY) $(UTILITIES)
|
||||
|
||||
update:
|
||||
@if [ -d .svn ]; then \
|
||||
@@ -160,37 +154,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 libpri.so.$(SONAME) libpri.so)
|
||||
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf $(DYNAMIC_LIBRARY) libpri.so)
|
||||
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
|
||||
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
|
||||
else
|
||||
install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
|
||||
install -f $(INSTALL_PREFIX)$(libdir) -m 755 $(DYNAMIC_LIBRARY)
|
||||
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf libpri.so.$(SONAME) libpri.so)
|
||||
( cd $(INSTALL_PREFIX)$(libdir) ; ln -sf $(DYNAMIC_LIBRARY) libpri.so)
|
||||
install -f $(INSTALL_PREFIX)$(libdir) -m 644 $(STATIC_LIBRARY)
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
@echo "Removing Libpri"
|
||||
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so.$(SONAME)
|
||||
rm -f $(INSTALL_PREFIX)$(libdir)/$(STATIC_LIBRARY)
|
||||
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.so
|
||||
rm -f $(INSTALL_PREFIX)$(libdir)/libpri.a
|
||||
rm -f $(INSTALL_PREFIX)$(libdir)/$(DYNAMIC_LIBRARY)
|
||||
rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
|
||||
|
||||
pritest: pritest.o
|
||||
$(CC) -o pritest pritest.o -L. -lpri $(CFLAGS)
|
||||
pritest: pritest.o $(STATIC_LIBRARY)
|
||||
$(CC) -o $@ $< $(STATIC_LIBRARY) $(CFLAGS)
|
||||
|
||||
testprilib.o: testprilib.c
|
||||
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE -o $@ -c $<
|
||||
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE $(MAKE_DEPS) -c -o $@ $<
|
||||
|
||||
testprilib: testprilib.o
|
||||
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
|
||||
testprilib: testprilib.o $(STATIC_LIBRARY)
|
||||
$(CC) -o $@ $< $(STATIC_LIBRARY) -lpthread $(CFLAGS)
|
||||
|
||||
pridump: pridump.o
|
||||
$(CC) -o pridump pridump.o -L. -lpri $(CFLAGS)
|
||||
pridump: pridump.o $(DYNAMIC_LIBRARY)
|
||||
$(CC) -o $@ $< -L. -lpri $(CFLAGS)
|
||||
|
||||
rosetest: rosetest.o
|
||||
$(CC) -o rosetest rosetest.o -L. -lpri $(CFLAGS)
|
||||
rosetest: rosetest.o $(STATIC_LIBRARY)
|
||||
$(CC) -o $@ $< $(STATIC_LIBRARY) $(CFLAGS)
|
||||
|
||||
MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
|
||||
|
||||
@@ -201,13 +195,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) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
|
||||
$(CC) $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
|
||||
$(LDCONFIG) $(LDCONFIG_FLAGS) .
|
||||
ln -sf libpri.so.$(SONAME) libpri.so
|
||||
ln -sf $(DYNAMIC_LIBRARY) libpri.so
|
||||
|
||||
version.c: FORCE
|
||||
@build_tools/make_version_c > $@.tmp
|
||||
@@ -215,9 +209,9 @@ version.c: FORCE
|
||||
@rm -f $@.tmp
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so *.lo *.so.$(SONAME)
|
||||
rm -f testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
rm -f pritest pridump
|
||||
rm -f *.o *.so *.lo
|
||||
rm -f $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
rm -f $(UTILITIES)
|
||||
rm -f .*.d
|
||||
|
||||
.PHONY:
|
||||
|
||||
@@ -25,7 +25,13 @@ FSM CC_PTMP_Agent
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -45,22 +51,26 @@ FSM CC_PTMP_Agent
|
||||
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 Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
State CC_STATE_REQUESTED {
|
||||
Epilog {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
}
|
||||
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
|
||||
Next_State CC_STATE_ACTIVATED;
|
||||
|
||||
@@ -20,7 +20,14 @@ FSM CC_PTMP_Agent
|
||||
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;
|
||||
}
|
||||
@@ -39,9 +46,13 @@ FSM CC_PTMP_Agent
|
||||
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 Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Action Stop_T_RETENTION;
|
||||
Action Set_Selfdestruct;
|
||||
@@ -49,7 +60,7 @@ FSM CC_PTMP_Agent
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
Action Stop_T_RETENTION;
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
@@ -58,7 +69,7 @@ FSM CC_PTMP_Agent
|
||||
State CC_STATE_REQUESTED {
|
||||
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
/* Start T_CCBS2 or T_CCNR2 depending upon CC mode. */
|
||||
Action Start_T_SUPERVISION;
|
||||
Action Reset_A_Status;
|
||||
@@ -67,7 +78,7 @@ FSM CC_PTMP_Agent
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Relese_LinkID;
|
||||
Action Release_LinkID;
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@ FSM CC_PTP_Agent
|
||||
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;
|
||||
}
|
||||
@@ -53,6 +57,10 @@ FSM CC_PTP_Agent
|
||||
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;
|
||||
|
||||
@@ -20,6 +20,11 @@ FSM CC_PTP_Agent
|
||||
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;
|
||||
@@ -46,6 +51,10 @@ FSM CC_PTP_Agent
|
||||
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;
|
||||
|
||||
@@ -41,6 +41,10 @@ FSM CC_QSIG_Agent
|
||||
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;
|
||||
|
||||
@@ -34,6 +34,10 @@ FSM CC_QSIG_Agent
|
||||
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;
|
||||
|
||||
224
libpri.h
224
libpri.h
@@ -547,6 +547,7 @@ struct pri_rerouting_data {
|
||||
#define PRI_SUBCMD_AOC_CHARGING_REQ_RSP 22 /*!< Advice Of Charge Request Response information */
|
||||
#define PRI_SUBCMD_MCID_REQ 23 /*!< Malicious Call ID Request */
|
||||
#define PRI_SUBCMD_MCID_RSP 24 /*!< Malicious Call ID Request response */
|
||||
#define PRI_SUBCMD_DISPLAY_TEXT 25 /*!< Received display ie text */
|
||||
|
||||
#if defined(STATUS_REQUEST_PLACE_HOLDER)
|
||||
struct pri_subcmd_status_request {
|
||||
@@ -967,6 +968,35 @@ struct pri_subcmd_mcid_rsp {
|
||||
int fail_code;
|
||||
};
|
||||
|
||||
struct pri_subcmd_display_txt {
|
||||
/*!
|
||||
* \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)
|
||||
*/
|
||||
int char_set;
|
||||
/*!
|
||||
* \brief Number of octets in the display message.
|
||||
* \note Not including any added null terminator.
|
||||
*/
|
||||
int length;
|
||||
/*!
|
||||
* \brief Display text data.
|
||||
* \note Null terminated on receive.
|
||||
* \note Does not need to be null terminated on send.
|
||||
*/
|
||||
char text[128];
|
||||
};
|
||||
|
||||
struct pri_subcommand {
|
||||
/*! PRI_SUBCMD_xxx defined values */
|
||||
int cmd;
|
||||
@@ -999,6 +1029,7 @@ struct pri_subcommand {
|
||||
struct pri_subcmd_aoc_e aoc_e;
|
||||
struct pri_subcmd_mcid_req mcid_req;
|
||||
struct pri_subcmd_mcid_rsp mcid_rsp;
|
||||
struct pri_subcmd_display_txt display;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -1182,6 +1213,7 @@ typedef struct pri_event_setup_ack {
|
||||
int channel;
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
int progressmask;
|
||||
} pri_event_setup_ack;
|
||||
|
||||
typedef struct pri_event_notify {
|
||||
@@ -1377,8 +1409,17 @@ const char *pri_facility_error2str(int facility_error_code);
|
||||
*/
|
||||
const char *pri_facility_reject2str(int facility_reject_code);
|
||||
|
||||
/* Acknowledge a call and place it on the given channel. Set info to non-zero if there
|
||||
is in-band data available on the channel */
|
||||
/*!
|
||||
* \brief Send the ALERTING message.
|
||||
*
|
||||
* \param pri D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||
* \param info Nonzero to include a progress ie indicating inband audio available (ie ringback).
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
/* Send a digit in overlap mode */
|
||||
@@ -1388,12 +1429,44 @@ int pri_information(struct pri *pri, q931_call *call, char digit);
|
||||
/* Send a keypad facility string of digits */
|
||||
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
||||
|
||||
/* Answer the incomplete(call without called number) call on the given channel.
|
||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
||||
/*!
|
||||
* \brief Send the SETUP_ACKNOWLEDGE message.
|
||||
*
|
||||
* \param pri D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
|
||||
/* Answer(CONNECT) the call on the given channel.
|
||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
||||
/*!
|
||||
* \brief Send the SETUP_ACKNOWLEDGE message.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||
* \param inband Nonzero to include a progress ie indicating inband audio available (ie dialtone).
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_setup_ack(struct pri *ctrl, q931_call *call, int channel, int nonisdn, int inband);
|
||||
|
||||
/*!
|
||||
* \brief Send the CONNECT message.
|
||||
*
|
||||
* \param pri D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
|
||||
/*!
|
||||
@@ -1590,11 +1663,11 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
|
||||
* \brief Send a MWI indication on the specified D channel.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param mailbox Controlling party number (NULL if not present).
|
||||
* \param mailbox Party receiving notification.
|
||||
* \param basic_service Basic service enum (-1 if not present).
|
||||
* \param num_messages NumberOfMessages (-1 if not present).
|
||||
* \param caller_id Controlling party privided number (NULL if not present).
|
||||
* \param timestamp Generalized Time format (NULL if not present).
|
||||
* \param caller_id Party leaving message (NULL if not present).
|
||||
* \param timestamp When message left. (Generalized Time format, NULL if not present)
|
||||
* \param message_reference Message reference number (-1 if not present).
|
||||
* \param message_status Message status: added(0), removed(1).
|
||||
*
|
||||
@@ -1605,6 +1678,27 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
int basic_service, int num_messages, const struct pri_party_id *caller_id,
|
||||
const char *timestamp, int message_reference, int message_status);
|
||||
|
||||
/*!
|
||||
* \brief Send a MWI indication on the specified D channel. (Take two)
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param mailbox Party receiving notification.
|
||||
* \param vm_id Voicemail system number (NULL if not present).
|
||||
* \param basic_service Basic service enum (-1 if not present).
|
||||
* \param num_messages NumberOfMessages (-1 if not present).
|
||||
* \param caller_id Party leaving message (NULL if not present).
|
||||
* \param timestamp When message left. (Generalized Time format, NULL if not present)
|
||||
* \param message_reference Message reference number (-1 if not present).
|
||||
* \param message_status Message status: added(0), removed(1).
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
const struct pri_party_id *vm_id, int basic_service, int num_messages,
|
||||
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
|
||||
int message_status);
|
||||
|
||||
/* Set service message support flag */
|
||||
int pri_set_service_message_support(struct pri *pri, int supportflag);
|
||||
|
||||
@@ -1640,7 +1734,17 @@ int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
|
||||
int pri_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause);
|
||||
|
||||
#define PRI_PROCEEDING_FULL
|
||||
/* Send call proceeding */
|
||||
/*!
|
||||
* \brief Send the PROCEEDING message.
|
||||
*
|
||||
* \param pri D channel controller.
|
||||
* \param c Q.931 call leg.
|
||||
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||
* \param info Nonzero to include a progress ie indicating inband audio available.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
|
||||
|
||||
/* Enable inband progress when a DISCONNECT is received */
|
||||
@@ -1840,6 +1944,80 @@ int pri_transfer_rsp(struct pri *ctrl, q931_call *call, int invoke_id, int is_su
|
||||
*/
|
||||
void pri_aoc_events_enable(struct pri *ctrl, int enable);
|
||||
|
||||
enum pri_layer2_persistence {
|
||||
PRI_L2_PERSISTENCE_DEFAULT,
|
||||
/*! Immediately bring layer 2 back up if the peer brings layer 2 down. */
|
||||
PRI_L2_PERSISTENCE_KEEP_UP,
|
||||
/*! Leave layer 2 down if the peer brings layer 2 down. */
|
||||
PRI_L2_PERSISTENCE_LEAVE_DOWN,
|
||||
#if 0 /* Possible future option. Would need to define how long to idle before dropping. */
|
||||
/*! Drop layer 2 on D channel idle. */
|
||||
PRI_L2_PERSISTENCE_IDLE_DROP,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Set the layer2 persistence option.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param option Layer 2 persistence to apply.
|
||||
*
|
||||
* \note
|
||||
* Not all values are supported by all modes.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_persistent_layer2_option(struct pri *ctrl, enum pri_layer2_persistence option);
|
||||
|
||||
#define PRI_DISPLAY_OPTION_BLOCK (1 << 0) /*!< Do not pass display text. */
|
||||
#define PRI_DISPLAY_OPTION_NAME_INITIAL (1 << 1) /*!< Use display in SETUP/CONNECT for name. */
|
||||
#define PRI_DISPLAY_OPTION_NAME_UPDATE (1 << 2) /*!< Use display in FACILITY/NOTIFY for COLP name if appropriate. */
|
||||
#define PRI_DISPLAY_OPTION_TEXT (1 << 3) /*!< Pass arbitrary display text in INFORMATION messages during call. */
|
||||
|
||||
/*!
|
||||
* \brief Set the display ie send policy options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param flags Option flags to apply.
|
||||
*
|
||||
* \note
|
||||
* If no flags set then legacy default behaviour.
|
||||
*
|
||||
* \note
|
||||
* Not all options are supported by all switches.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_display_options_send(struct pri *ctrl, unsigned long flags);
|
||||
|
||||
/*!
|
||||
* \brief Set the display ie receive policy options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param flags Option flags to apply.
|
||||
*
|
||||
* \note
|
||||
* If no flags set then legacy default behaviour.
|
||||
*
|
||||
* \note
|
||||
* Not all options are supported by all switches.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_display_options_receive(struct pri *ctrl, unsigned long flags);
|
||||
|
||||
/*!
|
||||
* \brief Send display text during a call.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param display Display text to send.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_display_text(struct pri *ctrl, q931_call *call, const struct pri_subcmd_display_txt *display);
|
||||
|
||||
/*!
|
||||
* \brief Set the call hold feature enable flag.
|
||||
*
|
||||
@@ -2001,6 +2179,27 @@ void pri_cc_status(struct pri *ctrl, long cc_id, int status);
|
||||
int pri_cc_call(struct pri *ctrl, long cc_id, q931_call *call, struct pri_sr *req);
|
||||
void pri_cc_cancel(struct pri *ctrl, long cc_id);
|
||||
|
||||
/* Date/time ie send policy option values. */
|
||||
#define PRI_DATE_TIME_SEND_DEFAULT 0 /*!< Send date/time ie default. */
|
||||
#define PRI_DATE_TIME_SEND_NO 1 /*!< Send date/time ie never. */
|
||||
#define PRI_DATE_TIME_SEND_DATE 2 /*!< Send date/time ie date only. */
|
||||
#define PRI_DATE_TIME_SEND_DATE_HH 3 /*!< Send date/time ie date and hour. */
|
||||
#define PRI_DATE_TIME_SEND_DATE_HHMM 4 /*!< Send date/time ie date, hour, and minute. */
|
||||
#define PRI_DATE_TIME_SEND_DATE_HHMMSS 5 /*!< Send date/time ie date, hour, minute, and second. */
|
||||
|
||||
/*!
|
||||
* \brief Set the date/time ie send policy option.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param option Policy option to set.
|
||||
*
|
||||
* \note
|
||||
* Only valid in NT mode.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_date_time_send_option(struct pri *ctrl, int option);
|
||||
|
||||
/* Get/Set PRI Timers */
|
||||
#define PRI_GETSET_TIMERS
|
||||
int pri_set_timer(struct pri *pri, int timer, int value);
|
||||
@@ -2032,7 +2231,7 @@ enum PRI_TIMERS_AND_COUNTERS {
|
||||
PRI_TIMER_T310, /*!< Maximum time between receiving a CALL_PROCEEDING and receiving a ALERT/CONNECT/DISCONNECT/PROGRESS */
|
||||
PRI_TIMER_T313, /*!< Wait for CONNECT acknowledge, CPE side only */
|
||||
PRI_TIMER_T314,
|
||||
PRI_TIMER_T316, /*!< Maximum time between transmitting a RESTART and receiving a RESTART ACK */
|
||||
PRI_TIMER_T316, /*!< Time to wait for a RESTART ACK before retransmitting RESTART. (Timer enabled if greater than zero.) */
|
||||
PRI_TIMER_T317,
|
||||
PRI_TIMER_T318,
|
||||
PRI_TIMER_T319,
|
||||
@@ -2073,6 +2272,9 @@ enum PRI_TIMERS_AND_COUNTERS {
|
||||
PRI_TIMER_QSIG_CC_T3, /*!< Max time to wait for user A to respond to user B availability. */
|
||||
PRI_TIMER_QSIG_CC_T4, /*!< Path reservation supervision timeout. */
|
||||
|
||||
PRI_TIMER_T312, /*!< Supervise broadcast SETUP message call reference retention. */
|
||||
PRI_TIMER_N316, /*!< Number of times to transmit RESTART before giving up if T316 enabled. */
|
||||
|
||||
/* Must be last in the enum list */
|
||||
PRI_MAX_TIMERS
|
||||
};
|
||||
|
||||
25
pri_aoc.c
25
pri_aoc.c
@@ -212,7 +212,7 @@ void aoc_etsi_aoc_request(struct pri *ctrl, q931_call *call, const struct rose_m
|
||||
struct pri_subcommand *subcmd;
|
||||
int request;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id, ROSE_ERROR_Gen_NotSubscribed);
|
||||
return;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ void aoc_etsi_aoc_s_currency(struct pri *ctrl, const struct rose_msg_invoke *inv
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -470,7 +470,7 @@ void aoc_etsi_aoc_s_special_arrangement(struct pri *ctrl, const struct rose_msg_
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -535,7 +535,7 @@ void aoc_etsi_aoc_d_currency(struct pri *ctrl, const struct rose_msg_invoke *inv
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -577,7 +577,7 @@ void aoc_etsi_aoc_d_charging_unit(struct pri *ctrl, const struct rose_msg_invoke
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -760,7 +760,7 @@ void aoc_etsi_aoc_e_currency(struct pri *ctrl, q931_call *call, const struct ros
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -828,7 +828,7 @@ void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struc
|
||||
}
|
||||
}
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -869,7 +869,6 @@ void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struc
|
||||
void pri_aoc_events_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->aoc_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1610,7 +1609,7 @@ static int aoc_e_encode(struct pri *ctrl, q931_call *call, const struct pri_subc
|
||||
|
||||
int pri_aoc_de_request_response_send(struct pri *ctrl, q931_call *call, int response, int invoke_id)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1629,7 +1628,7 @@ int pri_aoc_de_request_response_send(struct pri *ctrl, q931_call *call, int resp
|
||||
|
||||
int pri_aoc_s_request_response_send(struct pri *ctrl, q931_call *call, int invoke_id, const struct pri_subcmd_aoc_s *aoc_s)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1692,7 +1691,7 @@ int aoc_charging_request_send(struct pri *ctrl, q931_call *call, enum PRI_AOC_RE
|
||||
|
||||
int pri_aoc_s_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_s *aoc_s)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1711,7 +1710,7 @@ int pri_aoc_s_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_ao
|
||||
|
||||
int pri_aoc_d_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_d *aoc_d)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1729,7 +1728,7 @@ int pri_aoc_d_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_ao
|
||||
|
||||
int pri_aoc_e_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_e *aoc_e)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
91
pri_cc.c
91
pri_cc.c
@@ -61,7 +61,6 @@ struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned refere
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->ccbs_reference_id == reference_id) {
|
||||
/* Found the record */
|
||||
@@ -85,7 +84,6 @@ struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->call_linkage_id == linkage_id) {
|
||||
/* Found the record */
|
||||
@@ -110,7 +108,6 @@ static struct pri_cc_record *pri_cc_find_by_id(struct pri *ctrl, long cc_id)
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->record_id == cc_id) {
|
||||
/* Found the record */
|
||||
@@ -234,7 +231,6 @@ struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q
|
||||
struct q931_party_address addr_a;
|
||||
struct q931_party_address addr_b;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
addr_a = *party_a;
|
||||
addr_b = *party_b;
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
@@ -266,7 +262,6 @@ static int pri_cc_new_reference_id(struct pri *ctrl)
|
||||
long reference_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.last_reference_id = (ctrl->cc.last_reference_id + 1) & 0x7F;
|
||||
reference_id = ctrl->cc.last_reference_id;
|
||||
first_id = reference_id;
|
||||
@@ -298,7 +293,6 @@ static int pri_cc_new_linkage_id(struct pri *ctrl)
|
||||
long linkage_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.last_linkage_id = (ctrl->cc.last_linkage_id + 1) & 0x7F;
|
||||
linkage_id = ctrl->cc.last_linkage_id;
|
||||
first_id = linkage_id;
|
||||
@@ -330,7 +324,6 @@ static long pri_cc_new_id(struct pri *ctrl)
|
||||
long record_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
record_id = ++ctrl->cc.last_record_id;
|
||||
first_id = record_id;
|
||||
while (pri_cc_find_by_id(ctrl, record_id)) {
|
||||
@@ -386,7 +379,6 @@ static void pri_cc_delete_record(struct pri *ctrl, struct pri_cc_record *doomed)
|
||||
}
|
||||
pri_cc_disassociate_signaling_link(doomed);
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
|
||||
prev = ¤t->next, current = current->next) {
|
||||
if (current == doomed) {
|
||||
@@ -413,7 +405,6 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
|
||||
struct pri_cc_record *cc_record;
|
||||
long record_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
record_id = pri_cc_new_id(ctrl);
|
||||
if (record_id < 0) {
|
||||
return NULL;
|
||||
@@ -424,7 +415,7 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
|
||||
}
|
||||
|
||||
/* Initialize the new record */
|
||||
cc_record->master = ctrl;
|
||||
cc_record->ctrl = ctrl;
|
||||
cc_record->record_id = record_id;
|
||||
cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
|
||||
cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
|
||||
@@ -975,7 +966,7 @@ static unsigned char *enc_qsig_cc_request(struct pri *ctrl,
|
||||
|
||||
//msg.args.qsig.CcbsRequest.can_retain_service = 0;
|
||||
|
||||
switch (PRI_MASTER(ctrl)->cc.option.signaling_retention_req) {
|
||||
switch (ctrl->cc.option.signaling_retention_req) {
|
||||
case 0:/* Want release signaling link. */
|
||||
cc_record->option.retain_signaling_link = 0;
|
||||
|
||||
@@ -1954,7 +1945,6 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
struct q931_party_number party_a_number;
|
||||
const struct pri_cc_record *cc_record;
|
||||
unsigned char *new_pos;
|
||||
struct pri *master;
|
||||
unsigned idx;
|
||||
|
||||
pos = facility_encode_header(ctrl, pos, end, NULL);
|
||||
@@ -1966,8 +1956,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
msg.invoke_id = invoke->invoke_id;
|
||||
msg.operation = invoke->operation;
|
||||
|
||||
master = PRI_MASTER(ctrl);
|
||||
msg.args.etsi.CCBSInterrogate.recall_mode = master->cc.option.recall_mode;
|
||||
msg.args.etsi.CCBSInterrogate.recall_mode = ctrl->cc.option.recall_mode;
|
||||
|
||||
/* Convert the given party A number. */
|
||||
q931_party_number_init(&party_a_number);
|
||||
@@ -1979,7 +1968,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
|
||||
/* Build the CallDetails list. */
|
||||
idx = 0;
|
||||
for (cc_record = master->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID
|
||||
|| (!cc_record->is_ccnr) != (invoke->operation == ROSE_ETSI_CCBSInterrogate)) {
|
||||
/*
|
||||
@@ -2087,7 +2076,7 @@ int pri_cc_interrogate_rsp(struct pri *ctrl, q931_call *call, const struct rose_
|
||||
{
|
||||
int encode_result;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
return send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2134,7 +2123,7 @@ void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_ms
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2191,7 +2180,7 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
|
||||
/* Ignore CC request message since it did not come in on the correct message. */
|
||||
return;
|
||||
}
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2230,8 +2219,7 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
|
||||
party_a.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
} else {
|
||||
party_a.number.presentation =
|
||||
PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
party_a.number.presentation = PRES_NUMBER_NOT_AVAILABLE;
|
||||
}
|
||||
} else {
|
||||
party_a.number.presentation =
|
||||
@@ -2270,7 +2258,6 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
|
||||
*/
|
||||
void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
|
||||
{
|
||||
struct pri *master;
|
||||
struct pri_cc_record *cc_record;
|
||||
struct q931_party_address party_a;
|
||||
struct q931_party_address party_b;
|
||||
@@ -2279,8 +2266,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
/* Ignore CC request message since it did not come in on the correct message. */
|
||||
return;
|
||||
}
|
||||
master = PRI_MASTER(ctrl);
|
||||
if (!master->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
|
||||
ROSE_ERROR_QSIG_LongTermRejection);
|
||||
@@ -2302,7 +2288,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
|
||||
&invoke->args.qsig.CcbsRequest.subaddr_b);
|
||||
|
||||
cc_record = pri_cc_find_by_addressing(master, &party_a, &party_b,
|
||||
cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
|
||||
invoke->args.qsig.CcbsRequest.q931ie.length,
|
||||
invoke->args.qsig.CcbsRequest.q931ie.contents);
|
||||
if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
|
||||
@@ -2321,7 +2307,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
} else {
|
||||
/* The originator does not care. Do how we are configured. */
|
||||
cc_record->option.retain_signaling_link =
|
||||
master->cc.option.signaling_retention_rsp;
|
||||
ctrl->cc.option.signaling_retention_rsp;
|
||||
}
|
||||
if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
|
||||
/*
|
||||
@@ -2517,14 +2503,13 @@ void pri_cc_qsig_exec_possible(struct pri *ctrl, q931_call *call, int msgtype, c
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Convert the given call completion state to a string.
|
||||
*
|
||||
* \param state CC state to convert to string.
|
||||
*
|
||||
* \return String version of call completion state.
|
||||
*/
|
||||
static const char *pri_cc_fsm_state_str(enum CC_STATES state)
|
||||
const char *pri_cc_fsm_state_str(enum CC_STATES state)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
@@ -2568,14 +2553,13 @@ static const char *pri_cc_fsm_state_str(enum CC_STATES state)
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Convert the given call completion event to a string.
|
||||
*
|
||||
* \param event CC event to convert to string.
|
||||
*
|
||||
* \return String version of call completion event.
|
||||
*/
|
||||
static const char *pri_cc_fsm_event_str(enum CC_EVENTS event)
|
||||
const char *pri_cc_fsm_event_str(enum CC_EVENTS event)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
@@ -2626,6 +2610,9 @@ static const char *pri_cc_fsm_event_str(enum CC_EVENTS event)
|
||||
case CC_EVENT_CANCEL:
|
||||
str = "CC_EVENT_CANCEL";
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
str = "CC_EVENT_INTERNAL_CLEARING";
|
||||
break;
|
||||
case CC_EVENT_SIGNALING_GONE:
|
||||
str = "CC_EVENT_SIGNALING_GONE";
|
||||
break;
|
||||
@@ -2805,7 +2792,7 @@ static void pri_cc_timeout_t_retention(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_retention = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2857,7 +2844,7 @@ static void pri_cc_timeout_extended_t_ccbs1(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2911,7 +2898,7 @@ static void pri_cc_timeout_t_supervision(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_supervision = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2991,7 +2978,7 @@ static void pri_cc_timeout_t_recall(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_recall = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -3755,7 +3742,7 @@ static void pri_cc_indirect_status_rsp_a(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_rsp_a);
|
||||
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_rsp_a);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -3904,7 +3891,7 @@ static void pri_cc_indirect_status_a(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_a);
|
||||
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_a);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -4261,7 +4248,7 @@ static void pri_cc_post_hangup_signaling(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_HANGUP_SIGNALING);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_HANGUP_SIGNALING);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -4364,7 +4351,14 @@ static void pri_cc_fsm_ptmp_agent_pend_avail(struct pri *ctrl, q931_call *call,
|
||||
pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
|
||||
cc_record->state = CC_STATE_AVAILABLE;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
case CC_EVENT_CANCEL:
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
@@ -4397,6 +4391,10 @@ static void pri_cc_fsm_ptmp_agent_avail(struct pri *ctrl, q931_call *call, struc
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
@@ -5288,6 +5286,11 @@ static void pri_cc_fsm_ptp_agent_pend_avail(struct pri *ctrl, q931_call *call, s
|
||||
pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
|
||||
cc_record->state = CC_STATE_AVAILABLE;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
case CC_EVENT_CANCEL:
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
@@ -5328,6 +5331,10 @@ static void pri_cc_fsm_ptp_agent_avail(struct pri *ctrl, q931_call *call, struct
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
@@ -5927,6 +5934,10 @@ static void pri_cc_fsm_qsig_agent_avail(struct pri *ctrl, q931_call *call, struc
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
@@ -6803,7 +6814,7 @@ long pri_cc_available(struct pri *ctrl, q931_call *call)
|
||||
struct pri_cc_record *cc_record;
|
||||
long cc_id;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
if (call->cc.record) {
|
||||
@@ -6850,7 +6861,7 @@ long pri_cc_available(struct pri *ctrl, q931_call *call)
|
||||
break;
|
||||
}
|
||||
cc_record->call_linkage_id = linkage_id;
|
||||
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
|
||||
cc_record->signaling = ctrl->link.dummy_call;
|
||||
} else {
|
||||
cc_record = pri_cc_new_record(ctrl, call);
|
||||
if (!cc_record) {
|
||||
@@ -6894,7 +6905,7 @@ void pri_cc_qsig_determine_available(struct pri *ctrl, q931_call *call)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
@@ -7811,7 +7822,7 @@ int pri_cc_call(struct pri *ctrl, long cc_id, q931_call *call, struct pri_sr *re
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
if (!ctrl || !call || !req) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call) || !req) {
|
||||
return -1;
|
||||
}
|
||||
cc_record = pri_cc_find_by_id(ctrl, cc_id);
|
||||
|
||||
483
pri_facility.c
483
pri_facility.c
@@ -632,6 +632,9 @@ void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
|
||||
rose_copy_number_to_q931(ctrl, q931_number,
|
||||
&rose_presented->screened.number);
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
q931_number->presentation = PRES_NUMBER_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
q931_number->presentation |= PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
break;
|
||||
@@ -660,6 +663,9 @@ void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
|
||||
case 3: /* presentationRestrictedNumber */
|
||||
rose_copy_number_to_q931(ctrl, q931_number, &rose_presented->number);
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
q931_number->presentation = PRES_NUMBER_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -693,6 +699,9 @@ void rose_copy_presented_address_screened_to_id_q931(struct pri *ctrl,
|
||||
rose_copy_subaddress_to_q931(ctrl, &q931_address->subaddress,
|
||||
&rose_presented->screened.subaddress);
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
q931_address->number.presentation = PRES_NUMBER_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
q931_address->number.presentation |= PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
break;
|
||||
@@ -1746,11 +1755,11 @@ int mwi_message_send(struct pri *ctrl, q931_call *call, struct pri_sr *req, int
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode the facility ie contents.
|
||||
* \param end End of facility ie contents encoding data buffer.
|
||||
* \param mailbox Controlling party number (NULL if not present).
|
||||
* \param vm_id Controlling party number (NULL if not present).
|
||||
* \param basic_service Basic service enum (-1 if not present).
|
||||
* \param num_messages NumberOfMessages (-1 if not present).
|
||||
* \param caller_id Controlling party privided number (NULL if not present).
|
||||
* \param timestamp Generalized Time format (NULL if not present).
|
||||
* \param timestamp When message left. (Generalized Time format, NULL if not present)
|
||||
* \param message_reference Message reference number (-1 if not present).
|
||||
* \param message_status Message status: added(0), removed(1).
|
||||
*
|
||||
@@ -1758,7 +1767,7 @@ int mwi_message_send(struct pri *ctrl, q931_call *call, struct pri_sr *req, int
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, const struct pri_party_id *mailbox, int basic_service,
|
||||
unsigned char *end, const struct pri_party_id *vm_id, int basic_service,
|
||||
int num_messages, const struct pri_party_id *caller_id, const char *timestamp,
|
||||
int message_reference, int message_status)
|
||||
{
|
||||
@@ -1774,8 +1783,8 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
|
||||
msg.operation = ROSE_ETSI_MWIIndicate;
|
||||
msg.invoke_id = get_invokeid(ctrl);
|
||||
|
||||
if (mailbox && mailbox->number.valid) {
|
||||
pri_copy_party_number_to_q931(&number, &mailbox->number);
|
||||
if (vm_id && vm_id->number.valid) {
|
||||
pri_copy_party_number_to_q931(&number, &vm_id->number);
|
||||
q931_copy_number_to_rose(ctrl, &msg.args.etsi.MWIIndicate.controlling_user_number,
|
||||
&number);
|
||||
}
|
||||
@@ -1814,11 +1823,11 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Call leg to queue message.
|
||||
* \param mailbox Controlling party number (NULL if not present).
|
||||
* \param vm_id Voicemail system number (NULL if not present).
|
||||
* \param basic_service Basic service enum (-1 if not present).
|
||||
* \param num_messages NumberOfMessages (-1 if not present).
|
||||
* \param caller_id Controlling party privided number (NULL if not present).
|
||||
* \param timestamp Generalized Time format (NULL if not present).
|
||||
* \param caller_id Party leaving message (NULL if not present).
|
||||
* \param timestamp When message left. (Generalized Time format, NULL if not present)
|
||||
* \param message_reference Message reference number (-1 if not present).
|
||||
* \param message_status Message status: added(0), removed(1).
|
||||
*
|
||||
@@ -1826,14 +1835,14 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int rose_mwi_indicate_encode(struct pri *ctrl, struct q931_call *call,
|
||||
const struct pri_party_id *mailbox, int basic_service, int num_messages,
|
||||
const struct pri_party_id *vm_id, int basic_service, int num_messages,
|
||||
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
|
||||
int message_status)
|
||||
{
|
||||
unsigned char buffer[255];
|
||||
unsigned char *end;
|
||||
|
||||
end = enc_etsi_mwi_indicate_message(ctrl, buffer, buffer + sizeof(buffer), mailbox,
|
||||
end = enc_etsi_mwi_indicate_message(ctrl, buffer, buffer + sizeof(buffer), vm_id,
|
||||
basic_service, num_messages, caller_id, timestamp, message_reference,
|
||||
message_status);
|
||||
if (!end) {
|
||||
@@ -1843,11 +1852,13 @@ static int rose_mwi_indicate_encode(struct pri *ctrl, struct q931_call *call,
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
|
||||
}
|
||||
|
||||
int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
int basic_service, int num_messages, const struct pri_party_id *caller_id,
|
||||
const char *timestamp, int message_reference, int message_status)
|
||||
int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
const struct pri_party_id *vm_id, int basic_service, int num_messages,
|
||||
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
|
||||
int message_status)
|
||||
{
|
||||
struct q931_call *call;
|
||||
struct q931_party_id called;
|
||||
|
||||
if (!ctrl) {
|
||||
return -1;
|
||||
@@ -1859,7 +1870,7 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
if (!BRI_NT_PTMP(ctrl)) {
|
||||
return -1;
|
||||
}
|
||||
call = PRI_MASTER(ctrl)->dummy_call;
|
||||
call = ctrl->link.dummy_call;
|
||||
if (!call) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1868,9 +1879,11 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rose_mwi_indicate_encode(ctrl, call, mailbox, basic_service, num_messages,
|
||||
pri_copy_party_id_to_q931(&called, mailbox);
|
||||
q931_party_id_fixup(ctrl, &called);
|
||||
if (rose_mwi_indicate_encode(ctrl, call, vm_id, basic_service, num_messages,
|
||||
caller_id, timestamp, message_reference, message_status)
|
||||
|| q931_facility(ctrl, call)) {
|
||||
|| q931_facility_called(ctrl, call, &called)) {
|
||||
pri_message(ctrl,
|
||||
"Could not schedule facility message for MWI indicate message.\n");
|
||||
return -1;
|
||||
@@ -1878,6 +1891,14 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
int basic_service, int num_messages, const struct pri_party_id *caller_id,
|
||||
const char *timestamp, int message_reference, int message_status)
|
||||
{
|
||||
return pri_mwi_indicate_v2(ctrl, mailbox, mailbox, basic_service, num_messages,
|
||||
caller_id, timestamp, message_reference, message_status);
|
||||
}
|
||||
/* End MWI */
|
||||
|
||||
/* EECT functions */
|
||||
@@ -1907,7 +1928,7 @@ static unsigned char *enc_ni2_initiate_transfer(struct pri *ctrl, unsigned char
|
||||
msg.operation = ROSE_NI2_InitiateTransfer;
|
||||
msg.invoke_id = get_invokeid(ctrl);
|
||||
/* Let's do the trickery to make sure the flag is correct */
|
||||
msg.args.ni2.InitiateTransfer.call_reference = call->cr ^ 0x8000;
|
||||
msg.args.ni2.InitiateTransfer.call_reference = call->cr ^ Q931_CALL_REFERENCE_FLAG;
|
||||
pos = rose_encode_invoke(ctrl, pos, end, &msg);
|
||||
|
||||
return pos;
|
||||
@@ -2556,8 +2577,9 @@ static int etsi_ect_link_id_rsp(enum APDU_CALLBACK_REASON reason, struct pri *ct
|
||||
|
||||
switch (reason) {
|
||||
case APDU_CALLBACK_REASON_MSG_RESULT:
|
||||
call_2 = q931_find_call(ctrl, apdu->response.user.value);
|
||||
if (!call_2) {
|
||||
call_2 = apdu->response.user.ptr;
|
||||
if (!q931_is_call_valid(ctrl, call_2)) {
|
||||
/* Call is no longer present. */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2636,7 +2658,7 @@ int etsi_initiate_transfer(struct pri *ctrl, q931_call *call_1, q931_call *call_
|
||||
response.invoke_id = ctrl->last_invoke;
|
||||
response.timeout_time = ctrl->timers[PRI_TIMER_T_RESPONSE];
|
||||
response.callback = etsi_ect_link_id_rsp;
|
||||
response.user.value = call_2->cr;
|
||||
response.user.ptr = call_2;
|
||||
|
||||
/* Remember that if we queue a facility IE for a facility message we
|
||||
* have to explicitly send the facility message ourselves */
|
||||
@@ -3354,8 +3376,18 @@ int pri_call_add_standard_apdus(struct pri *ctrl, q931_call *call)
|
||||
*/
|
||||
int send_call_transfer_complete(struct pri *ctrl, q931_call *call, int call_status)
|
||||
{
|
||||
if (rose_call_transfer_complete_encode(ctrl, call, call_status)
|
||||
|| q931_facility(ctrl, call)) {
|
||||
int status;
|
||||
|
||||
status = rose_call_transfer_complete_encode(ctrl, call, call_status);
|
||||
if (!status) {
|
||||
if (!call_status && call->local_id.number.valid
|
||||
&& (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_UPDATE)) {
|
||||
status = q931_facility_display_name(ctrl, call, &call->local_id.name);
|
||||
} else {
|
||||
status = q931_facility(ctrl, call);
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
pri_message(ctrl,
|
||||
"Could not schedule facility message for call transfer completed.\n");
|
||||
return -1;
|
||||
@@ -3364,6 +3396,306 @@ int send_call_transfer_complete(struct pri *ctrl, q931_call *call, int call_stat
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the ETSI RequestSubaddress invoke message.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode the facility ie contents.
|
||||
* \param end End of facility ie contents encoding data buffer.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *enc_etsi_request_subaddress(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end)
|
||||
{
|
||||
struct rose_msg_invoke msg;
|
||||
|
||||
pos = facility_encode_header(ctrl, pos, end, NULL);
|
||||
if (!pos) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.operation = ROSE_ETSI_RequestSubaddress;
|
||||
msg.invoke_id = get_invokeid(ctrl);
|
||||
|
||||
pos = rose_encode_invoke(ctrl, pos, end, &msg);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Encode and queue the RequestSubaddress invoke message.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param call Call leg from which to encode message.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int rose_request_subaddress_encode(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
unsigned char buffer[256];
|
||||
unsigned char *end;
|
||||
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_EUROISDN_E1:
|
||||
case PRI_SWITCH_EUROISDN_T1:
|
||||
end = enc_etsi_request_subaddress(ctrl, buffer, buffer + sizeof(buffer));
|
||||
break;
|
||||
case PRI_SWITCH_QSIG:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (!end) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the ETSI SubaddressTransfer invoke message.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode the facility ie contents.
|
||||
* \param end End of facility ie contents encoding data buffer.
|
||||
* \param call Call leg from which to encode message.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *enc_etsi_subaddress_transfer(struct pri *ctrl, unsigned char *pos,
|
||||
unsigned char *end, struct q931_call *call)
|
||||
{
|
||||
struct rose_msg_invoke msg;
|
||||
|
||||
pos = facility_encode_header(ctrl, pos, end, NULL);
|
||||
if (!pos) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.operation = ROSE_ETSI_SubaddressTransfer;
|
||||
msg.invoke_id = get_invokeid(ctrl);
|
||||
|
||||
if (!call->local_id.subaddress.valid) {
|
||||
return NULL;
|
||||
}
|
||||
q931_copy_subaddress_to_rose(ctrl, &msg.args.etsi.SubaddressTransfer.subaddress,
|
||||
&call->local_id.subaddress);
|
||||
|
||||
pos = rose_encode_invoke(ctrl, pos, end, &msg);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the Q.SIG SubaddressTransfer invoke message.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param pos Starting position to encode the facility ie contents.
|
||||
* \param end End of facility ie contents encoding data buffer.
|
||||
* \param call Call leg from which to encode message.
|
||||
*
|
||||
* \retval Start of the next ASN.1 component to encode on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static unsigned char *enc_qsig_subaddress_transfer(struct pri *ctrl,
|
||||
unsigned char *pos, unsigned char *end, struct q931_call *call)
|
||||
{
|
||||
struct fac_extension_header header;
|
||||
struct rose_msg_invoke msg;
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.nfe_present = 1;
|
||||
header.nfe.source_entity = 0; /* endPINX */
|
||||
header.nfe.destination_entity = 0; /* endPINX */
|
||||
header.interpretation_present = 1;
|
||||
header.interpretation = 0; /* discardAnyUnrecognisedInvokePdu */
|
||||
pos = facility_encode_header(ctrl, pos, end, &header);
|
||||
if (!pos) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.operation = ROSE_QSIG_SubaddressTransfer;
|
||||
msg.invoke_id = get_invokeid(ctrl);
|
||||
|
||||
if (!call->local_id.subaddress.valid) {
|
||||
return NULL;
|
||||
}
|
||||
q931_copy_subaddress_to_rose(ctrl,
|
||||
&msg.args.qsig.SubaddressTransfer.redirection_subaddress,
|
||||
&call->local_id.subaddress);
|
||||
|
||||
pos = rose_encode_invoke(ctrl, pos, end, &msg);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode and queue the SubaddressTransfer invoke message.
|
||||
*
|
||||
* \param ctrl D channel controller for diagnostic messages or global options.
|
||||
* \param call Call leg from which to encode message.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int rose_subaddress_transfer_encode(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
unsigned char buffer[256];
|
||||
unsigned char *end;
|
||||
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_EUROISDN_E1:
|
||||
case PRI_SWITCH_EUROISDN_T1:
|
||||
end =
|
||||
enc_etsi_subaddress_transfer(ctrl, buffer, buffer + sizeof(buffer), call);
|
||||
break;
|
||||
case PRI_SWITCH_QSIG:
|
||||
end =
|
||||
enc_qsig_subaddress_transfer(ctrl, buffer, buffer + sizeof(buffer), call);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (!end) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Send a FACILITY SubaddressTransfer.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int send_subaddress_transfer(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
if (rose_subaddress_transfer_encode(ctrl, call)
|
||||
|| q931_facility(ctrl, call)) {
|
||||
pri_message(ctrl,
|
||||
"Could not schedule facility message for subaddress transfer.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Handle the received RequestSubaddress facility.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void etsi_request_subaddress(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
struct q931_party_name name;
|
||||
int changed = 0;
|
||||
|
||||
switch (call->notify) {
|
||||
case PRI_NOTIFY_TRANSFER_ACTIVE:
|
||||
if (q931_party_number_cmp(&call->remote_id.number, &call->redirection_number)) {
|
||||
/* The remote party number information changed. */
|
||||
call->remote_id.number = call->redirection_number;
|
||||
changed = 1;
|
||||
}
|
||||
/* Fall through */
|
||||
case PRI_NOTIFY_TRANSFER_ALERTING:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
if (q931_display_name_get(call, &name)) {
|
||||
if (q931_party_name_cmp(&call->remote_id.name, &name)) {
|
||||
/* The remote party name information changed. */
|
||||
call->remote_id.name = name;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (call->redirection_number.valid
|
||||
&& q931_party_number_cmp(&call->remote_id.number, &call->redirection_number)) {
|
||||
/* The remote party number information changed. */
|
||||
call->remote_id.number = call->redirection_number;
|
||||
changed = 1;
|
||||
}
|
||||
if (call->remote_id.subaddress.valid) {
|
||||
/*
|
||||
* Clear the subaddress as the remote party has been changed.
|
||||
* Any new subaddress will arrive later.
|
||||
*/
|
||||
q931_party_subaddress_init(&call->remote_id.subaddress);
|
||||
changed = 1;
|
||||
}
|
||||
if (changed) {
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send our subaddress back if we have one. */
|
||||
if (call->local_id.subaddress.valid) {
|
||||
send_subaddress_transfer(ctrl, call);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Handle the received SubaddressTransfer facility subaddress.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param subaddr Received subaddress of remote party.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void handle_subaddress_transfer(struct pri *ctrl, struct q931_call *call, const struct rosePartySubaddress *subaddr)
|
||||
{
|
||||
int changed = 0;
|
||||
struct q931_party_name name;
|
||||
struct q931_party_subaddress q931_subaddress;
|
||||
|
||||
q931_party_subaddress_init(&q931_subaddress);
|
||||
rose_copy_subaddress_to_q931(ctrl, &q931_subaddress, subaddr);
|
||||
if (q931_party_subaddress_cmp(&call->remote_id.subaddress, &q931_subaddress)) {
|
||||
call->remote_id.subaddress = q931_subaddress;
|
||||
changed = 1;
|
||||
}
|
||||
if (call->redirection_number.valid
|
||||
&& q931_party_number_cmp(&call->remote_id.number, &call->redirection_number)) {
|
||||
/* The remote party number information changed. */
|
||||
call->remote_id.number = call->redirection_number;
|
||||
changed = 1;
|
||||
}
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
if (q931_display_name_get(call, &name)) {
|
||||
if (q931_party_name_cmp(&call->remote_id.name, &name)) {
|
||||
/* The remote party name information changed. */
|
||||
call->remote_id.name = name;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode a plain facility ETSI error code.
|
||||
@@ -3632,7 +3964,7 @@ int pri_rerouting_rsp(struct pri *ctrl, q931_call *call, int invoke_id, enum PRI
|
||||
{
|
||||
enum rose_error_code rose_err;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3640,7 +3972,12 @@ int pri_rerouting_rsp(struct pri *ctrl, q931_call *call, int invoke_id, enum PRI
|
||||
rose_err = ROSE_ERROR_Gen_ResourceUnavailable;
|
||||
switch (code) {
|
||||
case PRI_REROUTING_RSP_OK_CLEAR:
|
||||
return rose_result_ok_encode(ctrl, call, Q931_DISCONNECT, invoke_id);
|
||||
/*
|
||||
* Send the response out on the next message which should be
|
||||
* either Q931_DISCONNECT or Q931_RELEASE depending upon who
|
||||
* initiates the disconnect first.
|
||||
*/
|
||||
return rose_result_ok_encode(ctrl, call, Q931_ANY_MESSAGE, invoke_id);
|
||||
case PRI_REROUTING_RSP_OK_RETAIN:
|
||||
return send_facility_result_ok(ctrl, call, invoke_id);
|
||||
case PRI_REROUTING_RSP_NOT_SUBSCRIBED:
|
||||
@@ -3673,7 +4010,7 @@ int pri_rerouting_rsp(struct pri *ctrl, q931_call *call, int invoke_id, enum PRI
|
||||
|
||||
int pri_transfer_rsp(struct pri *ctrl, q931_call *call, int invoke_id, int is_successful)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3804,7 +4141,7 @@ static int rose_mcid_req_encode(struct pri *ctrl, q931_call *call)
|
||||
|
||||
int pri_mcid_req_send(struct pri *ctrl, q931_call *call)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
if (call->cc.originated) {
|
||||
@@ -3824,7 +4161,6 @@ int pri_mcid_req_send(struct pri *ctrl, q931_call *call)
|
||||
void pri_mcid_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->mcid_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -3881,7 +4217,7 @@ void rose_handle_reject(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, reject->invoke_id);
|
||||
}
|
||||
@@ -3965,7 +4301,7 @@ void rose_handle_error(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, error->invoke_id);
|
||||
}
|
||||
@@ -4041,7 +4377,7 @@ void rose_handle_result(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, result->invoke_id);
|
||||
}
|
||||
@@ -4098,7 +4434,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_CallDeflection:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4166,7 +4502,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
&deflection);
|
||||
break;
|
||||
case ROSE_ETSI_CallRerouting:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4238,8 +4574,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
party_id.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
} else {
|
||||
party_id.number.presentation =
|
||||
PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
party_id.number.presentation = PRES_NUMBER_NOT_AVAILABLE;
|
||||
}
|
||||
} else {
|
||||
q931_party_number_init(&party_id.number);
|
||||
@@ -4364,7 +4699,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_EctExecute:
|
||||
if (!PRI_MASTER(ctrl)->transfer_support) {
|
||||
if (!ctrl->transfer_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4382,14 +4717,14 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_ETSI_RequestSubaddress:
|
||||
/* Ignore since we are not handling subaddresses yet. */
|
||||
etsi_request_subaddress(ctrl, call);
|
||||
break;
|
||||
#if 0 /* Not handled yet */
|
||||
case ROSE_ETSI_SubaddressTransfer:
|
||||
handle_subaddress_transfer(ctrl, call,
|
||||
&invoke->args.etsi.SubaddressTransfer.subaddress);
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_EctLinkIdRequest:
|
||||
if (!PRI_MASTER(ctrl)->transfer_support) {
|
||||
if (!ctrl->transfer_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_ResourceUnavailable);
|
||||
break;
|
||||
@@ -4404,17 +4739,33 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
send_ect_link_id_rsp(ctrl, call, invoke->invoke_id);
|
||||
break;
|
||||
case ROSE_ETSI_EctInform:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in remote_id.number */
|
||||
if (invoke->args.etsi.EctInform.redirection_present) {
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl,
|
||||
&call->remote_id.number, &invoke->args.etsi.EctInform.redirection);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the subaddress as the remote party has been changed.
|
||||
* Any new subaddress will arrive later.
|
||||
*/
|
||||
q931_party_subaddress_init(&call->remote_id.subaddress);
|
||||
|
||||
if (!invoke->args.etsi.EctInform.status) {
|
||||
/* The remote party for the transfer has not answered yet. */
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
|
||||
} else {
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
}
|
||||
|
||||
/* Send our subaddress back if we have one. */
|
||||
if (call->local_id.subaddress.valid) {
|
||||
send_subaddress_transfer(ctrl, call);
|
||||
}
|
||||
break;
|
||||
case ROSE_ETSI_EctLoopTest:
|
||||
/*
|
||||
@@ -4429,7 +4780,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
|
||||
case ROSE_ETSI_CallInfoRetain:
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
@@ -4444,7 +4795,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
if (!cc_record) {
|
||||
break;
|
||||
}
|
||||
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
|
||||
cc_record->signaling = ctrl->link.dummy_call;
|
||||
/*
|
||||
* Since we received this facility, we will not be allocating any
|
||||
* reference and linkage id's.
|
||||
@@ -4644,7 +4995,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
pri_cc_event(ctrl, call, cc_record, CC_EVENT_REMOTE_USER_FREE);
|
||||
break;
|
||||
case ROSE_ETSI_CCBS_T_Available:
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
@@ -4668,7 +5019,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
/* Don't even dignify this with a response. */
|
||||
break;
|
||||
}
|
||||
if (!PRI_MASTER(ctrl)->mcid_support) {
|
||||
if (!ctrl->mcid_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4710,6 +5061,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallingName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* CallingName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CallingName.name);
|
||||
@@ -4731,6 +5086,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CalledName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* CalledName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CalledName.name);
|
||||
@@ -4752,6 +5111,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_ConnectedName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* ConnectedName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.ConnectedName.name);
|
||||
@@ -4803,6 +5166,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallTransferActive:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
|
||||
/* connectedAddress is put in remote_id */
|
||||
@@ -4816,6 +5183,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CallTransferComplete:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in remote_id.number */
|
||||
rose_copy_presented_number_screened_to_q931(ctrl, &call->remote_id.number,
|
||||
&invoke->args.qsig.CallTransferComplete.redirection);
|
||||
@@ -4826,16 +5197,31 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
&invoke->args.qsig.CallTransferComplete.redirection_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the subaddress as the remote party has been changed.
|
||||
* Any new subaddress will arrive later.
|
||||
*/
|
||||
q931_party_subaddress_init(&call->remote_id.subaddress);
|
||||
|
||||
if (invoke->args.qsig.CallTransferComplete.call_status == 1) {
|
||||
/* The remote party for the transfer has not answered yet. */
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
|
||||
} else {
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
}
|
||||
|
||||
/* Send our subaddress back if we have one. */
|
||||
if (call->local_id.subaddress.valid) {
|
||||
send_subaddress_transfer(ctrl, call);
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CallTransferUpdate:
|
||||
party_id = call->remote_id;
|
||||
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &party_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in party_id.number */
|
||||
rose_copy_presented_number_screened_to_q931(ctrl, &party_id.number,
|
||||
&invoke->args.qsig.CallTransferUpdate.redirection);
|
||||
@@ -4858,10 +5244,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0 /* Not handled yet */
|
||||
case ROSE_QSIG_SubaddressTransfer:
|
||||
handle_subaddress_transfer(ctrl, call,
|
||||
&invoke->args.qsig.SubaddressTransfer.redirection_subaddress);
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_PathReplacement:
|
||||
anfpr_pathreplacement_respond(ctrl, call, ie);
|
||||
break;
|
||||
@@ -4876,7 +5262,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallRerouting:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -5167,8 +5553,9 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
#endif /* Not handled yet */
|
||||
default:
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, "!! ROSE invoke operation not handled! %s\n",
|
||||
rose_operation2str(invoke->operation));
|
||||
pri_message(ctrl,
|
||||
"!! ROSE invoke operation not handled on switchtype:%s! %s\n",
|
||||
pri_switch2str(ctrl->switchtype), rose_operation2str(invoke->operation));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -221,6 +221,8 @@ int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const
|
||||
int send_reroute_request(struct pri *ctrl, q931_call *call, const struct q931_party_id *caller, const struct q931_party_redirecting *deflection, int subscription_option);
|
||||
|
||||
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
|
||||
int rose_request_subaddress_encode(struct pri *ctrl, struct q931_call *call);
|
||||
int send_subaddress_transfer(struct pri *ctrl, struct q931_call *call);
|
||||
|
||||
int rose_diverting_leg_information1_encode(struct pri *pri, q931_call *call);
|
||||
int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
|
||||
233
pri_internal.h
233
pri_internal.h
@@ -60,6 +60,9 @@ struct pri_sched {
|
||||
/*! 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. */
|
||||
@@ -76,8 +79,10 @@ struct pri {
|
||||
void *userdata;
|
||||
/*! Accumulated pri_message() line. (Valid in master record only) */
|
||||
struct pri_msg_line *msg_line;
|
||||
struct pri *subchannel; /* Sub-channel if appropriate */
|
||||
struct pri *master; /* Master channel if appropriate */
|
||||
/*! 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;
|
||||
@@ -85,6 +90,8 @@ struct pri {
|
||||
unsigned num_slots;
|
||||
/*! Maximum timer slots currently needed. */
|
||||
unsigned max_used;
|
||||
/*! First timer id in this timer pool. */
|
||||
unsigned first_id;
|
||||
} sched;
|
||||
int debug; /* Debug stuff */
|
||||
int state; /* State of D-channel */
|
||||
@@ -93,9 +100,9 @@ struct pri {
|
||||
int localtype; /* Local network type (unknown, network, cpe) */
|
||||
int remotetype; /* Remote network type (unknown, network, cpe) */
|
||||
|
||||
int sapi;
|
||||
int tei;
|
||||
int protodisc;
|
||||
int protodisc; /* Layer 3 protocol discriminator */
|
||||
|
||||
unsigned int nfas:1;/* TRUE if this D channel is involved with an NFAS group */
|
||||
unsigned int bri:1;
|
||||
unsigned int acceptinbanddisconnect:1; /* Should we allow inband progress after DISCONNECT? */
|
||||
unsigned int sendfacility:1;
|
||||
@@ -111,65 +118,35 @@ struct pri {
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
/*! 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;
|
||||
|
||||
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 */
|
||||
q931_call **callpool;
|
||||
q931_call *localpool;
|
||||
struct q931_call **callpool;
|
||||
struct 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) */
|
||||
|
||||
@@ -207,6 +184,15 @@ 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) */
|
||||
@@ -369,10 +355,6 @@ struct pri_sr {
|
||||
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. */
|
||||
@@ -447,9 +429,10 @@ struct decoded_bc {
|
||||
|
||||
/* q931_call datastructure */
|
||||
struct q931_call {
|
||||
struct pri *pri; /* PRI */
|
||||
struct pri *pri; /* D channel controller (master) */
|
||||
struct q921_link *link; /* Q.921 link associated with this call. */
|
||||
struct q931_call *next;
|
||||
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) */
|
||||
@@ -563,9 +546,9 @@ struct q931_call {
|
||||
|
||||
/*! \brief Incoming call transfer state. */
|
||||
enum INCOMING_CT_STATE incoming_ct_state;
|
||||
/*! Call hold supplementary state. */
|
||||
/*! Call hold supplementary state. Valid on master call record only. */
|
||||
enum Q931_HOLD_STATE hold_state;
|
||||
/*! Call hold event timer */
|
||||
/*! Call hold event timer. Valid on master call record only. */
|
||||
int hold_timer;
|
||||
|
||||
int deflection_in_progress; /*!< CallDeflection for NT PTMP in progress. */
|
||||
@@ -590,7 +573,7 @@ struct q931_call {
|
||||
int is_link_id_valid;
|
||||
|
||||
/* Bridged call info */
|
||||
q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
|
||||
struct 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:
|
||||
@@ -599,11 +582,14 @@ 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;
|
||||
int performing_fake_clearing;
|
||||
/*! TRUE if the master call is processing a hangup. Don't destroy it now. */
|
||||
int master_hanging_up;
|
||||
/*!
|
||||
* \brief Master call controlling this call.
|
||||
* \note Always valid. Master and normal calls point to self.
|
||||
@@ -636,8 +622,59 @@ struct q931_call {
|
||||
unsigned char initially_redirected;
|
||||
} cc;
|
||||
|
||||
/* AOC charge requesting on Setup */
|
||||
/*! 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 {
|
||||
@@ -699,6 +736,8 @@ enum CC_EVENTS {
|
||||
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. */
|
||||
@@ -744,8 +783,8 @@ enum CC_PARTY_A_AVAILABILITY {
|
||||
struct pri_cc_record {
|
||||
/*! Next call-completion record in the list */
|
||||
struct pri_cc_record *next;
|
||||
/*! Master D channel control structure. */
|
||||
struct pri *master;
|
||||
/*! D channel control structure. */
|
||||
struct pri *ctrl;
|
||||
/*! Original call that is offered CC availability. (NULL if no longer exists.) */
|
||||
struct q931_call *original_call;
|
||||
/*!
|
||||
@@ -881,11 +920,35 @@ struct d_ctrl_dummy {
|
||||
struct q931_call dummy_call;
|
||||
};
|
||||
|
||||
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
|
||||
/*! 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 pri_event *pri_schedule_run(struct pri *pri);
|
||||
|
||||
extern void pri_schedule_del(struct pri *pri, int ev);
|
||||
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 pri_event *pri_mkerror(struct pri *pri, char *errstr);
|
||||
|
||||
@@ -894,10 +957,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);
|
||||
|
||||
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 pri_link_destroy(struct q921_link *link);
|
||||
struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei);
|
||||
|
||||
void q931_init_call_record(struct pri *ctrl, struct q931_call *call, int cr);
|
||||
void q931_init_call_record(struct q921_link *link, struct q931_call *call, int cr);
|
||||
|
||||
void pri_sr_init(struct pri_sr *req);
|
||||
|
||||
@@ -945,9 +1008,16 @@ 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);
|
||||
@@ -955,27 +1025,31 @@ 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_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
|
||||
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));
|
||||
|
||||
/*!
|
||||
* \brief Get the master PRI control structure.
|
||||
* \brief Get the NFAS master PRI control structure.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Master PRI control structure.
|
||||
* \return NFAS master PRI control structure.
|
||||
*/
|
||||
static inline struct pri *PRI_MASTER(struct pri *ctrl)
|
||||
static inline struct pri *PRI_NFAS_MASTER(struct pri *ctrl)
|
||||
{
|
||||
while (ctrl->master) {
|
||||
if (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
return ctrl;
|
||||
@@ -993,10 +1067,8 @@ static inline int BRI_NT_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_NETWORK
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
&& my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1011,10 +1083,8 @@ static inline int BRI_TE_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_CPE
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
&& my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1029,8 +1099,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -1046,8 +1114,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -1063,9 +1129,7 @@ static inline int PTP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_PRI;
|
||||
return my_ctrl->link.tei == Q921_TEI_PRI;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1080,9 +1144,7 @@ static inline int PTMP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_GROUP;
|
||||
return my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
#define Q931_DUMMY_CALL_REFERENCE -1
|
||||
@@ -1094,14 +1156,13 @@ 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 q931_call *call)
|
||||
static inline int q931_is_dummy_call(const struct q931_call *call)
|
||||
{
|
||||
return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline short get_invokeid(struct pri *ctrl)
|
||||
{
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
return ++ctrl->last_invoke;
|
||||
}
|
||||
|
||||
|
||||
118
pri_q921.h
118
pri_q921.h
@@ -57,6 +57,8 @@
|
||||
#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
|
||||
@@ -69,13 +71,16 @@
|
||||
#define Q921_SAPI_LAYER2_MANAGEMENT 63
|
||||
|
||||
|
||||
#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
|
||||
/*! Q.921 TEI management message type */
|
||||
enum q921_tei_identity {
|
||||
Q921_TEI_IDENTITY_REQUEST = 1,
|
||||
Q921_TEI_IDENTITY_ASSIGNED = 2,
|
||||
Q921_TEI_IDENTITY_DENIED = 3,
|
||||
Q921_TEI_IDENTITY_CHECK_REQUEST = 4,
|
||||
Q921_TEI_IDENTITY_CHECK_RESPONSE = 5,
|
||||
Q921_TEI_IDENTITY_REMOVE = 6,
|
||||
Q921_TEI_IDENTITY_VERIFY = 7,
|
||||
};
|
||||
|
||||
typedef struct q921_header {
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
@@ -158,11 +163,17 @@ 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 */
|
||||
int transmitted; /* Have we been transmitted */
|
||||
q921_i h;
|
||||
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. */
|
||||
} q921_frame;
|
||||
|
||||
#define Q921_INC(j) (j) = (((j) + 1) % 128)
|
||||
@@ -180,24 +191,101 @@ 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 showraw, int txrx);
|
||||
extern void q921_dump(struct pri *pri, q921_h *h, int len, int debugflags, int txrx);
|
||||
|
||||
/* Bring up the D-channel */
|
||||
extern void q921_start(struct pri *pri);
|
||||
void q921_start(struct q921_link *link);
|
||||
void q921_bring_layer2_up(struct pri *ctrl);
|
||||
|
||||
//extern void q921_reset(struct pri *pri, int reset_iqueue);
|
||||
|
||||
extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
|
||||
|
||||
extern int q921_transmit_iframe(struct pri *pri, int tei, void *buf, int len, int cr);
|
||||
int q921_transmit_iframe(struct q921_link *link, void *buf, int len, int cr);
|
||||
|
||||
extern int q921_transmit_uiframe(struct pri *pri, void *buf, int len);
|
||||
int q921_transmit_uiframe(struct q921_link *link, void *buf, int len);
|
||||
|
||||
extern pri_event *q921_dchannel_up(struct pri *pri);
|
||||
|
||||
|
||||
24
pri_q931.h
24
pri_q931.h
@@ -138,9 +138,6 @@ 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
|
||||
@@ -443,6 +440,8 @@ 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 */
|
||||
@@ -450,13 +449,11 @@ 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
|
||||
|
||||
extern int q931_receive(struct pri *pri, int tei, q931_h *h, int len);
|
||||
int q931_receive(struct q921_link *link, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
@@ -468,7 +465,7 @@ 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 *pri, q931_call *call, int channel, int nonisdn);
|
||||
extern int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn, int inband);
|
||||
|
||||
extern int q931_information(struct pri *pri, q931_call *call, char digit);
|
||||
|
||||
@@ -491,8 +488,7 @@ extern int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode);
|
||||
|
||||
extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
|
||||
|
||||
struct q931_call *q931_find_call(struct pri *ctrl, int cr);
|
||||
struct q931_call *q931_new_call(struct pri *pri);
|
||||
struct q931_call *q931_new_call(struct pri *ctrl);
|
||||
|
||||
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
|
||||
|
||||
@@ -502,7 +498,15 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
|
||||
|
||||
void q931_destroycall(struct pri *pri, q931_call *c);
|
||||
|
||||
extern void q931_dl_indication(struct pri *pri, int event);
|
||||
enum Q931_DL_EVENT {
|
||||
Q931_DL_EVENT_NONE,
|
||||
Q931_DL_EVENT_DL_ESTABLISH_IND,
|
||||
Q931_DL_EVENT_DL_ESTABLISH_CONFIRM,
|
||||
Q931_DL_EVENT_DL_RELEASE_IND,
|
||||
Q931_DL_EVENT_DL_RELEASE_CONFIRM,
|
||||
Q931_DL_EVENT_TEI_REMOVAL,
|
||||
};
|
||||
void q931_dl_event(struct q921_link *link, enum Q931_DL_EVENT event);
|
||||
|
||||
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);
|
||||
|
||||
16
pridump.c
16
pridump.c
@@ -42,7 +42,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <zaptel/zaptel.h>
|
||||
#include <dahdi/user.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 zt_params p;
|
||||
struct dahdi_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, ZT_GET_PARAMS, &p)) {
|
||||
if (ioctl(dfd, DAHDI_GET_PARAMS, &p)) {
|
||||
fprintf(stderr, "Unable to get parameters on '%s': %s\n", dev, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if ((p.sigtype != ZT_SIG_HDLCRAW) && (p.sigtype != ZT_SIG_HDLCFCS)) {
|
||||
if ((p.sigtype != DAHDI_SIG_HDLCRAW) && (p.sigtype != DAHDI_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, 1, txrx);
|
||||
q921_dump(pri, h, len, PRI_DEBUG_ALL, 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 int pri_bridge(int d1, int d2)
|
||||
static void pri_bridge(int d1, int d2)
|
||||
{
|
||||
char buf[1024];
|
||||
fd_set fds;
|
||||
@@ -94,8 +94,8 @@ static int pri_bridge(int d1, int d2)
|
||||
max = d1;
|
||||
if (max < d2)
|
||||
max = d2;
|
||||
ioctl(d1, ZT_GETEVENT, &e);
|
||||
ioctl(d2, ZT_GETEVENT, &e);
|
||||
ioctl(d1, DAHDI_GETEVENT, &e);
|
||||
ioctl(d2, DAHDI_GETEVENT, &e);
|
||||
res = select(max + 1, &fds, NULL, NULL, NULL);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Select returned %d: %s\n", res, strerror(errno));
|
||||
|
||||
108
prisched.c
108
prisched.c
@@ -38,13 +38,15 @@
|
||||
/*! Initial number of scheduled timer slots. */
|
||||
#define SCHED_EVENTS_INITIAL 128
|
||||
/*!
|
||||
* Maximum number of scheduled timer slots.
|
||||
* Should be a power of 2 multiple of SCHED_EVENTS_INITIAL.
|
||||
* \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;
|
||||
|
||||
/* Scheduler routines */
|
||||
|
||||
@@ -87,6 +89,23 @@ static int pri_schedule_grow(struct pri *ctrl)
|
||||
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. */
|
||||
@@ -106,15 +125,12 @@ 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.
|
||||
*/
|
||||
int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data)
|
||||
unsigned pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), void *data)
|
||||
{
|
||||
unsigned max_used;
|
||||
unsigned x;
|
||||
struct timeval tv;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
max_used = ctrl->sched.max_used;
|
||||
for (x = 0; x < max_used; ++x) {
|
||||
if (!ctrl->sched.timer[x].callback) {
|
||||
@@ -141,7 +157,7 @@ int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), v
|
||||
ctrl->sched.timer[x].when = tv;
|
||||
ctrl->sched.timer[x].callback = function;
|
||||
ctrl->sched.timer[x].data = data;
|
||||
return x + 1;
|
||||
return ctrl->sched.first_id + x;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -156,9 +172,6 @@ struct timeval *pri_schedule_next(struct pri *ctrl)
|
||||
struct timeval *closest = NULL;
|
||||
unsigned x;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
/* 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) {
|
||||
@@ -196,9 +209,6 @@ static pri_event *__pri_schedule_run(struct pri *ctrl, struct timeval *tv)
|
||||
void (*callback)(void *);
|
||||
void *data;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
max_used = ctrl->sched.max_used;
|
||||
for (x = 0; x < max_used; ++x) {
|
||||
if (ctrl->sched.timer[x].callback
|
||||
@@ -240,19 +250,73 @@ 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, int id)
|
||||
void pri_schedule_del(struct pri *ctrl, unsigned id)
|
||||
{
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
struct pri *nfas;
|
||||
|
||||
if (0 < id && id <= ctrl->sched.num_slots) {
|
||||
ctrl->sched.timer[id - 1].callback = NULL;
|
||||
} else if (id) {
|
||||
pri_error(ctrl, "Asked to delete sched id %d??? num_slots=%d\n", id,
|
||||
ctrl->sched.num_slots);
|
||||
if (!id) {
|
||||
/* Disabled/unscheduled event id. */
|
||||
return;
|
||||
}
|
||||
if (ctrl->sched.first_id <= id
|
||||
&& id <= ctrl->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
|
||||
ctrl->sched.timer[id - ctrl->sched.first_id].callback = NULL;
|
||||
return;
|
||||
}
|
||||
if (ctrl->nfas) {
|
||||
/* Try to find the timer on another D channel. */
|
||||
for (nfas = PRI_NFAS_MASTER(ctrl); nfas; nfas = nfas->slave) {
|
||||
if (nfas->sched.first_id <= id
|
||||
&& id <= nfas->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
|
||||
nfas->sched.timer[id - nfas->sched.first_id].callback = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
pri_error(ctrl,
|
||||
"Asked to delete sched id 0x%08x??? first_id=0x%08x, num_slots=0x%08x\n", id,
|
||||
ctrl->sched.first_id, ctrl->sched.num_slots);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Is the scheduled event this callback.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param id Scheduled event id to check.
|
||||
* 0 is a disabled/unscheduled event id.
|
||||
* \param function Callback function to call when timeout.
|
||||
* \param data Value to give callback function when timeout.
|
||||
*
|
||||
* \return TRUE if scheduled event has the callback.
|
||||
*/
|
||||
int pri_schedule_check(struct pri *ctrl, unsigned id, void (*function)(void *data), void *data)
|
||||
{
|
||||
struct pri *nfas;
|
||||
|
||||
if (!id) {
|
||||
/* Disabled/unscheduled event id. */
|
||||
return 0;
|
||||
}
|
||||
if (ctrl->sched.first_id <= id
|
||||
&& id <= ctrl->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
|
||||
return ctrl->sched.timer[id - ctrl->sched.first_id].callback == function
|
||||
&& ctrl->sched.timer[id - ctrl->sched.first_id].data == data;
|
||||
}
|
||||
if (ctrl->nfas) {
|
||||
/* Try to find the timer on another D channel. */
|
||||
for (nfas = PRI_NFAS_MASTER(ctrl); nfas; nfas = nfas->slave) {
|
||||
if (nfas->sched.first_id <= id
|
||||
&& id <= nfas->sched.first_id + (SCHED_EVENTS_MAX - 1)) {
|
||||
return nfas->sched.timer[id - nfas->sched.first_id].callback == function
|
||||
&& nfas->sched.timer[id - nfas->sched.first_id].data == data;
|
||||
}
|
||||
}
|
||||
}
|
||||
pri_error(ctrl,
|
||||
"Asked to check sched id 0x%08x??? first_id=0x%08x, num_slots=0x%08x\n", id,
|
||||
ctrl->sched.first_id, ctrl->sched.num_slots);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,10 @@ static void do_channel(int fd)
|
||||
int i=0;
|
||||
|
||||
while ((res = read(fd, buf, READ_SIZE)) > 0 && (i++ < 1000)) {
|
||||
write(fd, buf, res);
|
||||
if (write(fd, buf, res) == -1) {
|
||||
fprintf(stderr, "--!! Failed write: %d\n", errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
54
rose.c
54
rose.c
@@ -1237,6 +1237,34 @@ 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* */
|
||||
};
|
||||
|
||||
@@ -1292,6 +1320,19 @@ 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
|
||||
@@ -1317,19 +1358,6 @@ 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* */
|
||||
};
|
||||
|
||||
|
||||
22
testprilib.c
22
testprilib.c
@@ -48,13 +48,10 @@
|
||||
#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
|
||||
@@ -66,7 +63,7 @@
|
||||
#define PRI_DEF_NODETYPE PRI_CPE
|
||||
#define PRI_DEF_SWITCHTYPE PRI_SWITCH_NI2
|
||||
|
||||
static struct pri *first, *cur;
|
||||
static struct pri *first;
|
||||
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -159,9 +156,9 @@ static void testmsg(struct pri *pri, char *s)
|
||||
*c = '\0';
|
||||
c++;
|
||||
}
|
||||
if (keeplast)
|
||||
if (keeplast || !pri)
|
||||
printf("%s", s);
|
||||
else if (cur == first)
|
||||
else if (pri == first)
|
||||
printf("-1 %s", s);
|
||||
else
|
||||
printf("-2 %s", s);
|
||||
@@ -185,9 +182,9 @@ static void testerr(struct pri *pri, char *s)
|
||||
*c = '\0';
|
||||
c++;
|
||||
}
|
||||
if (keeplast)
|
||||
if (keeplast || !pri)
|
||||
printf("%s", s);
|
||||
else if (cur == first)
|
||||
else if (pri == first)
|
||||
printf("=1 %s", s);
|
||||
else
|
||||
printf("=2 %s", s);
|
||||
@@ -207,7 +204,7 @@ static void *dchan(void *data)
|
||||
/* Joint D-channel */
|
||||
struct pri *pri = data;
|
||||
struct timeval *next, tv;
|
||||
pri_event *e;
|
||||
pri_event *e = NULL;
|
||||
fd_set fds;
|
||||
int res;
|
||||
for(;;) {
|
||||
@@ -228,7 +225,6 @@ 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) {
|
||||
@@ -238,9 +234,9 @@ static void *dchan(void *data)
|
||||
}
|
||||
if (e) {
|
||||
if (first == pri) {
|
||||
event1(e->gen.pri, e);
|
||||
event1(pri, e);
|
||||
} else {
|
||||
event2(e->gen.pri, e);
|
||||
event2(pri, e);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
Reference in New Issue
Block a user