Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
533b3bde8a | ||
|
|
47b2ff8860 | ||
|
|
782a08d0e1 | ||
|
|
28553ff8cb | ||
|
|
1a0927ca23 | ||
|
|
de78c8d37f | ||
|
|
cdb844c16b | ||
|
|
75bf8f0a20 | ||
|
|
5e3581c977 | ||
|
|
d9c6cc68a5 | ||
|
|
27808e3640 | ||
|
|
4af121db62 | ||
|
|
053a38202e | ||
|
|
fffb7babaf | ||
|
|
f78400fc07 | ||
|
|
a7eaec1aaa | ||
|
|
17649b363b | ||
|
|
2c159d4685 | ||
|
|
6078b21698 | ||
|
|
4e7c3d1462 | ||
|
|
5947536965 | ||
|
|
c5ec479bd2 |
80
Makefile
80
Makefile
@@ -10,15 +10,15 @@
|
||||
# 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
|
||||
@@ -65,43 +65,21 @@ 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_OPT) $(COVERAGE_CFLAGS)
|
||||
$(STATIC_OBJS)
|
||||
CFLAGS ?= -g
|
||||
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
|
||||
INSTALL_PREFIX=$(DESTDIR)
|
||||
INSTALL_BASE=/usr
|
||||
libdir?=$(INSTALL_BASE)/lib
|
||||
ifneq ($(findstring Darwin,$(OSARCH)),)
|
||||
SOFLAGS=-dynamic -bundle -Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace
|
||||
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=-shared -Wl,-h$(DYNAMIC_LIBRARY) $(COVERAGE_LDFLAGS)
|
||||
SOFLAGS=$(LDFLAGS) -shared -Wl,-h$(DYNAMIC_LIBRARY) $(COVERAGE_LDFLAGS)
|
||||
LDCONFIG = /sbin/ldconfig
|
||||
endif
|
||||
ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX XGNUX))
|
||||
@@ -115,11 +93,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 .)
|
||||
@@ -145,7 +125,7 @@ CFLAGS += -m32
|
||||
SOFLAGS += -m32
|
||||
endif
|
||||
|
||||
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
all: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY) $(UTILITIES)
|
||||
|
||||
update:
|
||||
@if [ -d .svn ]; then \
|
||||
@@ -171,37 +151,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
|
||||
|
||||
@@ -218,7 +198,7 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
|
||||
$(DYNAMIC_LIBRARY): $(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
|
||||
@@ -226,9 +206,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:
|
||||
|
||||
74
libpri-1.4.14-summary.html
Normal file
74
libpri-1.4.14-summary.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Release Summary - libpri-1.4.14</title></head>
|
||||
<body>
|
||||
<h1 align="center"><a name="top">Release Summary</a></h1>
|
||||
<h3 align="center">libpri-1.4.14</h3>
|
||||
<h3 align="center">Date: 2012-12-20</h3>
|
||||
<h3 align="center"><asteriskteam@digium.com></h3>
|
||||
<hr/>
|
||||
<h2 align="center">Table of Contents</h2>
|
||||
<ol>
|
||||
<li><a href="#summary">Summary</a></li>
|
||||
<li><a href="#contributors">Contributors</a></li>
|
||||
<li><a href="#issues">Closed Issues</a></li>
|
||||
<li><a href="#commits">Other Changes</a></li>
|
||||
<li><a href="#diffstat">Diffstat</a></li>
|
||||
</ol>
|
||||
<hr/>
|
||||
<a name="summary"><h2 align="center">Summary</h2></a>
|
||||
<center><a href="#top">[Back to Top]</a></center><br/><p>This release includes only bug fixes. The changes included were made only to address problems that have been identified in this release series. Users should be able to safely upgrade to this version if this release series is already in use. Users considering upgrading from a previous release series are strongly encouraged to review the UPGRADE.txt document as well as the CHANGES document for information about upgrading to this release series.</p>
|
||||
<p>The data in this summary reflects changes that have been made since the previous release, libpri-1.4.13.</p>
|
||||
<hr/>
|
||||
<a name="contributors"><h2 align="center">Contributors</h2></a>
|
||||
<center><a href="#top">[Back to Top]</a></center><br/><p>This table lists the people who have submitted code, those that have tested patches, as well as those that reported issues on the issue tracker that were resolved in this release. For coders, the number is how many of their patches (of any size) were committed into this release. For testers, the number is the number of times their name was listed as assisting with testing a patch. Finally, for reporters, the number is the number of issues that they reported that were closed by commits that went into this release.</p>
|
||||
<table width="100%" border="0">
|
||||
<tr>
|
||||
<td width="33%"><h3>Coders</h3></td>
|
||||
<td width="33%"><h3>Testers</h3></td>
|
||||
<td width="33%"><h3>Reporters</h3></td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
2 rmudgett<br/>
|
||||
2 Tzafrir Cohen<br/>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
2 tzafrir<br/>
|
||||
1 nmerrett<br/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr/>
|
||||
<a name="issues"><h2 align="center">Closed Issues</h2></a>
|
||||
<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p>
|
||||
<h3>Category: General</h3><br/>
|
||||
<a href="https://issues.asterisk.org/jira/browse/PRI-145">PRI-145</a>: Unchecked write in pritest<br/>
|
||||
Revision: <a href="http://svn.digium.com/view/libpri/branches/1.4?view=revision&revision=2305">2305</a><br/>
|
||||
Reporter: tzafrir<br/>
|
||||
Coders: Tzafrir Cohen<br/>
|
||||
<br/>
|
||||
<a href="https://issues.asterisk.org/jira/browse/PRI-147">PRI-147</a>: Normal Clearing in Progress Message is ignored<br/>
|
||||
Revision: <a href="http://svn.digium.com/view/libpri/branches/1.4?view=revision&revision=2308">2308</a><br/>
|
||||
Reporter: nmerrett<br/>
|
||||
Coders: rmudgett<br/>
|
||||
<br/>
|
||||
<hr/>
|
||||
<a name="commits"><h2 align="center">Commits Not Associated with an Issue</h2></a>
|
||||
<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all changes that went into this release that did not directly close an issue from the issue tracker. The commits may have been marked as being related to an issue. If that is the case, the issue numbers are listed here, as well.</p>
|
||||
<table width="100%" border="1">
|
||||
<tr><td><b>Revision</b></td><td><b>Author</b></td><td><b>Summary</b></td><td><b>Issues Referenced</b></td></tr><tr><td><a href="http://svn.digium.com/view/libpri/branches/1.4?view=revision&revision=2307">2307</a></td><td>rmudgett</td><td>Fix compiler error with ALERTING_NO_PROGRESS define.</td>
|
||||
<td></td></tr></table>
|
||||
<hr/>
|
||||
<a name="diffstat"><h2 align="center">Diffstat Results</h2></a>
|
||||
<center><a href="#top">[Back to Top]</a></center><br/><p>This is a summary of the changes to the source code that went into this release that was generated using the diffstat utility.</p>
|
||||
<pre>
|
||||
pritest.c | 5 +++
|
||||
q931.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||||
2 files changed, 71 insertions(+), 13 deletions(-)
|
||||
</pre><br/>
|
||||
<hr/>
|
||||
</body>
|
||||
</html>
|
||||
108
libpri-1.4.14-summary.txt
Normal file
108
libpri-1.4.14-summary.txt
Normal file
@@ -0,0 +1,108 @@
|
||||
Release Summary
|
||||
|
||||
libpri-1.4.14
|
||||
|
||||
Date: 2012-12-20
|
||||
|
||||
<asteriskteam@digium.com>
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Summary
|
||||
2. Contributors
|
||||
3. Closed Issues
|
||||
4. Other Changes
|
||||
5. Diffstat
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Summary
|
||||
|
||||
[Back to Top]
|
||||
|
||||
This release includes only bug fixes. The changes included were made only
|
||||
to address problems that have been identified in this release series.
|
||||
Users should be able to safely upgrade to this version if this release
|
||||
series is already in use. Users considering upgrading from a previous
|
||||
release series are strongly encouraged to review the UPGRADE.txt document
|
||||
as well as the CHANGES document for information about upgrading to this
|
||||
release series.
|
||||
|
||||
The data in this summary reflects changes that have been made since the
|
||||
previous release, libpri-1.4.13.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Contributors
|
||||
|
||||
[Back to Top]
|
||||
|
||||
This table lists the people who have submitted code, those that have
|
||||
tested patches, as well as those that reported issues on the issue tracker
|
||||
that were resolved in this release. For coders, the number is how many of
|
||||
their patches (of any size) were committed into this release. For testers,
|
||||
the number is the number of times their name was listed as assisting with
|
||||
testing a patch. Finally, for reporters, the number is the number of
|
||||
issues that they reported that were closed by commits that went into this
|
||||
release.
|
||||
|
||||
Coders Testers Reporters
|
||||
2 rmudgett 2 tzafrir
|
||||
2 Tzafrir Cohen 1 nmerrett
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Closed Issues
|
||||
|
||||
[Back to Top]
|
||||
|
||||
This is a list of all issues from the issue tracker that were closed by
|
||||
changes that went into this release.
|
||||
|
||||
Category: General
|
||||
|
||||
PRI-145: Unchecked write in pritest
|
||||
Revision: 2305
|
||||
Reporter: tzafrir
|
||||
Coders: Tzafrir Cohen
|
||||
|
||||
PRI-147: Normal Clearing in Progress Message is ignored
|
||||
Revision: 2308
|
||||
Reporter: nmerrett
|
||||
Coders: rmudgett
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Commits Not Associated with an Issue
|
||||
|
||||
[Back to Top]
|
||||
|
||||
This is a list of all changes that went into this release that did not
|
||||
directly close an issue from the issue tracker. The commits may have been
|
||||
marked as being related to an issue. If that is the case, the issue
|
||||
numbers are listed here, as well.
|
||||
|
||||
+------------------------------------------------------------------------+
|
||||
| Revision | Author | Summary | Issues |
|
||||
| | | | Referenced |
|
||||
|----------+----------+-------------------------------------+------------|
|
||||
| 2307 | rmudgett | Fix compiler error with | |
|
||||
| | | ALERTING_NO_PROGRESS define. | |
|
||||
+------------------------------------------------------------------------+
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Diffstat Results
|
||||
|
||||
[Back to Top]
|
||||
|
||||
This is a summary of the changes to the source code that went into this
|
||||
release that was generated using the diffstat utility.
|
||||
|
||||
pritest.c | 5 +++
|
||||
q931.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||||
2 files changed, 71 insertions(+), 13 deletions(-)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
28
libpri.h
28
libpri.h
@@ -1892,6 +1892,31 @@ 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. */
|
||||
@@ -2154,7 +2179,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,
|
||||
@@ -2196,6 +2221,7 @@ enum PRI_TIMERS_AND_COUNTERS {
|
||||
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
|
||||
|
||||
64
pri.c
64
pri.c
@@ -81,6 +81,7 @@ static const struct pri_timer_table pri_timer[] = {
|
||||
{ "T313", PRI_TIMER_T313, PRI_ALL_SWITCHES },
|
||||
{ "T314", PRI_TIMER_T314, PRI_ALL_SWITCHES },
|
||||
{ "T316", PRI_TIMER_T316, PRI_ALL_SWITCHES },
|
||||
{ "N316", PRI_TIMER_N316, PRI_ALL_SWITCHES },
|
||||
{ "T317", PRI_TIMER_T317, PRI_ALL_SWITCHES },
|
||||
{ "T318", PRI_TIMER_T318, PRI_ALL_SWITCHES },
|
||||
{ "T319", PRI_TIMER_T319, PRI_ALL_SWITCHES },
|
||||
@@ -184,6 +185,10 @@ static void pri_default_timers(struct pri *ctrl, int switchtype)
|
||||
ctrl->timers[PRI_TIMER_T309] = 6 * 1000; /* Time to wait before clearing calls in case of D-channel transient event. Q.931 specifies 6-90 seconds */
|
||||
ctrl->timers[PRI_TIMER_T312] = (4 + 2) * 1000;/* Supervise broadcast SETUP message call reference retention. T303 + 2 seconds */
|
||||
ctrl->timers[PRI_TIMER_T313] = 4 * 1000; /* Wait for CONNECT acknowledge, CPE side only */
|
||||
#if 0 /* Default disable the T316 timer otherwise the user cannot disable it. */
|
||||
ctrl->timers[PRI_TIMER_T316] = 2 * 60 * 1000; /* RESTART retransmit timer */
|
||||
#endif
|
||||
ctrl->timers[PRI_TIMER_N316] = 2; /* Send RESTART this many times before giving up. */
|
||||
|
||||
ctrl->timers[PRI_TIMER_TM20] = 2500; /* Max time awaiting XID response - Q.921 Appendix IV */
|
||||
ctrl->timers[PRI_TIMER_NM20] = 3; /* Number of XID retransmits - Q.921 Appendix IV */
|
||||
@@ -290,6 +295,27 @@ static int __pri_write(struct pri *pri, void *buf, int buflen)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Determine the default layer 2 persistence option.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Default layer 2 persistence option. (legacy behaviour default)
|
||||
*/
|
||||
static enum pri_layer2_persistence pri_l2_persistence_option_default(struct pri *ctrl)
|
||||
{
|
||||
enum pri_layer2_persistence persistence;
|
||||
|
||||
if (PTMP_MODE(ctrl)) {
|
||||
persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
|
||||
} else {
|
||||
persistence = PRI_L2_PERSISTENCE_KEEP_UP;
|
||||
}
|
||||
|
||||
return persistence;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Determine the default display text send options.
|
||||
@@ -558,6 +584,7 @@ static struct pri *pri_ctrl_new(int fd, int node, int switchtype, pri_io_cb rd,
|
||||
ctrl->q931_rxcount = 0;
|
||||
ctrl->q931_txcount = 0;
|
||||
|
||||
ctrl->l2_persistence = pri_l2_persistence_option_default(ctrl);
|
||||
ctrl->display_flags.send = pri_display_options_send_default(ctrl);
|
||||
ctrl->display_flags.receive = pri_display_options_receive_default(ctrl);
|
||||
switch (switchtype) {
|
||||
@@ -951,7 +978,7 @@ void pri_copy_party_name_to_q931(struct q931_party_name *q931_name, const struct
|
||||
q931_party_name_init(q931_name);
|
||||
if (pri_name->valid) {
|
||||
q931_name->valid = 1;
|
||||
q931_name->presentation = pri_name->presentation;
|
||||
q931_name->presentation = pri_name->presentation & PRI_PRES_RESTRICTION;
|
||||
q931_name->char_set = pri_name->char_set;
|
||||
libpri_copy_string(q931_name->str, pri_name->str, sizeof(q931_name->str));
|
||||
}
|
||||
@@ -970,7 +997,8 @@ void pri_copy_party_number_to_q931(struct q931_party_number *q931_number, const
|
||||
q931_party_number_init(q931_number);
|
||||
if (pri_number->valid) {
|
||||
q931_number->valid = 1;
|
||||
q931_number->presentation = pri_number->presentation;
|
||||
q931_number->presentation = pri_number->presentation
|
||||
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
|
||||
q931_number->plan = pri_number->plan;
|
||||
libpri_copy_string(q931_number->str, pri_number->str, sizeof(q931_number->str));
|
||||
}
|
||||
@@ -1772,7 +1800,8 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
enum PRI_TIMERS_AND_COUNTERS tmr;
|
||||
|
||||
tmr = pri_timer[idx].number;
|
||||
if (0 <= ctrl->timers[tmr]) {
|
||||
if (0 <= ctrl->timers[tmr]
|
||||
|| tmr == PRI_TIMER_T316) {
|
||||
used = pri_snprintf(buf, used, buf_size, " %s: %d\n",
|
||||
pri_timer[idx].name, ctrl->timers[tmr]);
|
||||
}
|
||||
@@ -1940,13 +1969,14 @@ int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int cal
|
||||
q931_party_id_init(&sr->caller);
|
||||
if (caller) {
|
||||
sr->caller.number.valid = 1;
|
||||
sr->caller.number.presentation = callerpres;
|
||||
sr->caller.number.presentation = callerpres
|
||||
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
|
||||
sr->caller.number.plan = callerplan;
|
||||
libpri_copy_string(sr->caller.number.str, caller, sizeof(sr->caller.number.str));
|
||||
|
||||
if (callername) {
|
||||
sr->caller.name.valid = 1;
|
||||
sr->caller.name.presentation = callerpres;
|
||||
sr->caller.name.presentation = callerpres & PRI_PRES_RESTRICTION;
|
||||
sr->caller.name.char_set = PRI_CHAR_SET_ISO8859_1;
|
||||
libpri_copy_string(sr->caller.name.str, callername,
|
||||
sizeof(sr->caller.name.str));
|
||||
@@ -1970,7 +2000,8 @@ int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int
|
||||
q931_party_redirecting_init(&sr->redirecting);
|
||||
if (num && num[0]) {
|
||||
sr->redirecting.from.number.valid = 1;
|
||||
sr->redirecting.from.number.presentation = pres;
|
||||
sr->redirecting.from.number.presentation = pres
|
||||
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
|
||||
sr->redirecting.from.number.plan = plan;
|
||||
libpri_copy_string(sr->redirecting.from.number.str, num,
|
||||
sizeof(sr->redirecting.from.number.str));
|
||||
@@ -2165,6 +2196,27 @@ void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention)
|
||||
}
|
||||
}
|
||||
|
||||
void pri_persistent_layer2_option(struct pri *ctrl, enum pri_layer2_persistence option)
|
||||
{
|
||||
if (!ctrl) {
|
||||
return;
|
||||
}
|
||||
if (PTMP_MODE(ctrl)) {
|
||||
switch (option) {
|
||||
case PRI_L2_PERSISTENCE_DEFAULT:
|
||||
ctrl->l2_persistence = pri_l2_persistence_option_default(ctrl);
|
||||
break;
|
||||
case PRI_L2_PERSISTENCE_KEEP_UP:
|
||||
case PRI_L2_PERSISTENCE_LEAVE_DOWN:
|
||||
ctrl->l2_persistence = option;
|
||||
break;
|
||||
}
|
||||
if (ctrl->l2_persistence == PRI_L2_PERSISTENCE_KEEP_UP) {
|
||||
q921_bring_layer2_up(ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pri_display_options_send(struct pri *ctrl, unsigned long flags)
|
||||
{
|
||||
if (!ctrl) {
|
||||
|
||||
3
pri_cc.c
3
pri_cc.c
@@ -2219,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 =
|
||||
|
||||
@@ -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;
|
||||
@@ -1871,6 +1880,7 @@ int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
}
|
||||
|
||||
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_called(ctrl, call, &called)) {
|
||||
@@ -4564,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);
|
||||
|
||||
@@ -120,6 +120,8 @@ struct pri {
|
||||
|
||||
/*! 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. */
|
||||
@@ -623,7 +625,9 @@ struct q931_call {
|
||||
/*! Display text ie contents. */
|
||||
struct {
|
||||
/*! Display ie text. NULL if not present or consumed as remote name. */
|
||||
const char *text;
|
||||
const unsigned char *text;
|
||||
/*! Full IE code of received display text */
|
||||
int full_ie;
|
||||
/*! Length of display text. */
|
||||
unsigned char length;
|
||||
/*!
|
||||
@@ -645,6 +649,29 @@ struct q931_call {
|
||||
|
||||
/* AOC charge requesting on Setup */
|
||||
int aoc_charging_request;
|
||||
|
||||
unsigned int slotmap_size:1;/* TRUE if the slotmap is E1 (32 bits). */
|
||||
|
||||
/*! 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 {
|
||||
|
||||
@@ -252,7 +252,7 @@ struct q921_link {
|
||||
int n202_counter;
|
||||
/*! Max idle time */
|
||||
int t203_timer;
|
||||
/*! PTP restart delay timer */
|
||||
/*! Layer 2 persistence restart delay timer */
|
||||
int restart_timer;
|
||||
|
||||
/* MDL variables */
|
||||
@@ -273,10 +273,11 @@ static inline int Q921_ADD(int a, int b)
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
|
||||
|
||||
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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
395
q921.c
395
q921.c
@@ -186,7 +186,7 @@ static int q921_transmit(struct pri *ctrl, q921_h *h, int len)
|
||||
ctrl->q921_txcount++;
|
||||
/* Just send it raw */
|
||||
if (ctrl->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
|
||||
q921_dump(ctrl, h, len, ctrl->debug & PRI_DEBUG_Q921_RAW, 1);
|
||||
q921_dump(ctrl, h, len, ctrl->debug, 1);
|
||||
/* Write an extra two bytes for the FCS */
|
||||
res = ctrl->write_func ? ctrl->write_func(ctrl, h, len + 2) : 0;
|
||||
if (res != (len + 2)) {
|
||||
@@ -235,7 +235,10 @@ static void t202_expire(void *vlink)
|
||||
link->t202_timer =
|
||||
pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T202], t202_expire, link);
|
||||
|
||||
++link->n202_counter;
|
||||
if (ctrl->l2_persistence != PRI_L2_PERSISTENCE_KEEP_UP) {
|
||||
/* Only try to get a TEI for N202 times if layer 2 is not persistent. */
|
||||
++link->n202_counter;
|
||||
}
|
||||
if (!link->t202_timer || link->n202_counter > ctrl->timers[PRI_TIMER_N202]) {
|
||||
if (!link->t202_timer) {
|
||||
pri_error(ctrl, "Could not start T202 timer.");
|
||||
@@ -530,6 +533,49 @@ static void stop_t200(struct q921_link *link)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Initiate bringing up layer 2 link.
|
||||
*
|
||||
* \param link Layer 2 link to bring up.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void kick_start_link(struct q921_link *link)
|
||||
{
|
||||
struct pri *ctrl;
|
||||
|
||||
ctrl = link->ctrl;
|
||||
|
||||
switch (link->state) {
|
||||
case Q921_TEI_UNASSIGNED:
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
pri_message(ctrl, "Kick starting link from no TEI.\n");
|
||||
}
|
||||
q921_setstate(link, Q921_ESTABLISH_AWAITING_TEI);
|
||||
q921_tei_request(link);
|
||||
break;
|
||||
case Q921_ASSIGN_AWAITING_TEI:
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
pri_message(ctrl, "Kick starting link when get TEI.\n");
|
||||
}
|
||||
q921_setstate(link, Q921_ESTABLISH_AWAITING_TEI);
|
||||
break;
|
||||
case Q921_TEI_ASSIGNED:
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
pri_message(ctrl, "SAPI/TEI=%d/%d Kick starting link\n", link->sapi,
|
||||
link->tei);
|
||||
}
|
||||
q921_discard_iqueue(link);
|
||||
q921_establish_data_link(link);
|
||||
link->l3_initiated = 1;
|
||||
q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void restart_timer_expire(void *vlink)
|
||||
{
|
||||
struct q921_link *link = vlink;
|
||||
@@ -537,19 +583,12 @@ static void restart_timer_expire(void *vlink)
|
||||
|
||||
ctrl = link->ctrl;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
pri_message(ctrl, "SAPI/TEI=%d/%d Kick starting link\n", link->sapi, link->tei);
|
||||
}
|
||||
|
||||
link->restart_timer = 0;
|
||||
|
||||
switch (link->state) {
|
||||
case Q921_TEI_ASSIGNED:
|
||||
/* Try to bring layer 2 up. */
|
||||
q921_discard_iqueue(link);
|
||||
q921_establish_data_link(link);
|
||||
link->l3_initiated = 1;
|
||||
q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
|
||||
kick_start_link(link);
|
||||
break;
|
||||
default:
|
||||
/* Looks like someone forgot to stop the restart timer. */
|
||||
@@ -568,6 +607,7 @@ static void restart_timer_stop(struct q921_link *link)
|
||||
link->restart_timer = 0;
|
||||
}
|
||||
|
||||
/*! \note Only call on the transition to state Q921_TEI_ASSIGNED or already there. */
|
||||
static void restart_timer_start(struct q921_link *link)
|
||||
{
|
||||
struct pri *ctrl;
|
||||
@@ -583,21 +623,27 @@ static void restart_timer_start(struct q921_link *link)
|
||||
pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], restart_timer_expire, link);
|
||||
}
|
||||
|
||||
static pri_event *q921_ptp_delay_restart(struct q921_link *link)
|
||||
/*! \note Only call on the transition to state Q921_TEI_ASSIGNED or already there. */
|
||||
static pri_event *q921_check_delay_restart(struct q921_link *link)
|
||||
{
|
||||
pri_event *ev;
|
||||
struct pri *ctrl;
|
||||
|
||||
ctrl = link->ctrl;
|
||||
|
||||
if (PTP_MODE(ctrl)) {
|
||||
if (ctrl->l2_persistence == PRI_L2_PERSISTENCE_KEEP_UP) {
|
||||
/*
|
||||
* For PTP links:
|
||||
* This is where we act a bit like L3 instead of L2, since we've
|
||||
* got an L3 that depends on us keeping L2 automatically alive
|
||||
* and happy for PTP links.
|
||||
* and happy.
|
||||
*
|
||||
* For PTMP links:
|
||||
* We can optionally keep L2 automatically alive and happy.
|
||||
*/
|
||||
restart_timer_start(link);
|
||||
|
||||
}
|
||||
if (PTP_MODE(ctrl)) {
|
||||
switch (link->state) {
|
||||
case Q921_MULTI_FRAME_ESTABLISHED:
|
||||
case Q921_TIMER_RECOVERY:
|
||||
@@ -616,6 +662,31 @@ static pri_event *q921_ptp_delay_restart(struct q921_link *link)
|
||||
return ev;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Bring all layer 2 links up.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void q921_bring_layer2_up(struct pri *ctrl)
|
||||
{
|
||||
struct q921_link *link;
|
||||
|
||||
if (PTMP_MODE(ctrl)) {
|
||||
/* Don't start with the broadcast link. */
|
||||
link = ctrl->link.next;
|
||||
} else {
|
||||
link = &ctrl->link;
|
||||
}
|
||||
for (; link; link = link->next) {
|
||||
if (!link->restart_timer) {
|
||||
/* A restart on the link is not already in the works. */
|
||||
kick_start_link(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the equivalent of the I-Frame queued up path in Figure B.7 in MULTI_FRAME_ESTABLISHED */
|
||||
static int q921_send_queued_iframes(struct q921_link *link)
|
||||
{
|
||||
@@ -859,7 +930,7 @@ static void t200_expire(void *vlink)
|
||||
q921_send_sabme(link);
|
||||
start_t200(link);
|
||||
} else {
|
||||
q921_ptp_delay_restart(link);
|
||||
q921_check_delay_restart(link);
|
||||
q921_discard_iqueue(link);
|
||||
q921_mdl_error(link, 'G');
|
||||
q921_setstate(link, Q921_TEI_ASSIGNED);
|
||||
@@ -873,7 +944,7 @@ static void t200_expire(void *vlink)
|
||||
q921_send_disc(link, 1);
|
||||
start_t200(link);
|
||||
} else {
|
||||
q921_ptp_delay_restart(link);
|
||||
q921_check_delay_restart(link);
|
||||
q921_mdl_error(link, 'H');
|
||||
/* DL-RELEASE confirm */
|
||||
q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
|
||||
@@ -1116,7 +1187,7 @@ static void q921_dump_iqueue_info(struct q921_link *link)
|
||||
|
||||
static void q921_dump_pri_by_h(struct pri *ctrl, char direction_tag, q921_h *h);
|
||||
|
||||
void q921_dump(struct pri *ctrl, q921_h *h, int len, int showraw, int txrx)
|
||||
void q921_dump(struct pri *ctrl, q921_h *h, int len, int debugflags, int txrx)
|
||||
{
|
||||
int x;
|
||||
const char *type;
|
||||
@@ -1125,9 +1196,11 @@ void q921_dump(struct pri *ctrl, q921_h *h, int len, int showraw, int txrx)
|
||||
direction_tag = txrx ? '>' : '<';
|
||||
|
||||
pri_message(ctrl, "\n");
|
||||
q921_dump_pri_by_h(ctrl, direction_tag, h);
|
||||
if (debugflags & PRI_DEBUG_Q921_DUMP) {
|
||||
q921_dump_pri_by_h(ctrl, direction_tag, h);
|
||||
}
|
||||
|
||||
if (showraw) {
|
||||
if (debugflags & PRI_DEBUG_Q921_RAW) {
|
||||
char *buf = malloc(len * 3 + 1);
|
||||
int buflen = 0;
|
||||
if (buf) {
|
||||
@@ -1138,132 +1211,134 @@ void q921_dump(struct pri *ctrl, q921_h *h, int len, int showraw, int txrx)
|
||||
}
|
||||
}
|
||||
|
||||
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
|
||||
case 0:
|
||||
case 2:
|
||||
pri_message(ctrl, "%c Informational frame:\n", direction_tag);
|
||||
break;
|
||||
case 1:
|
||||
pri_message(ctrl, "%c Supervisory frame:\n", direction_tag);
|
||||
break;
|
||||
case 3:
|
||||
pri_message(ctrl, "%c Unnumbered frame:\n", direction_tag);
|
||||
break;
|
||||
}
|
||||
|
||||
pri_message(ctrl, "%c SAPI: %02d C/R: %d EA: %d\n",
|
||||
direction_tag,
|
||||
h->h.sapi,
|
||||
h->h.c_r,
|
||||
h->h.ea1);
|
||||
pri_message(ctrl, "%c TEI: %03d EA: %d\n",
|
||||
direction_tag,
|
||||
h->h.tei,
|
||||
h->h.ea2);
|
||||
|
||||
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
|
||||
case 0:
|
||||
case 2:
|
||||
/* Informational frame */
|
||||
pri_message(ctrl, "%c N(S): %03d 0: %d\n",
|
||||
direction_tag,
|
||||
h->i.n_s,
|
||||
h->i.ft);
|
||||
pri_message(ctrl, "%c N(R): %03d P: %d\n",
|
||||
direction_tag,
|
||||
h->i.n_r,
|
||||
h->i.p_f);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 4);
|
||||
break;
|
||||
case 1:
|
||||
/* Supervisory frame */
|
||||
type = "???";
|
||||
switch (h->s.ss) {
|
||||
if (debugflags & PRI_DEBUG_Q921_DUMP) {
|
||||
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
|
||||
case 0:
|
||||
type = "RR (receive ready)";
|
||||
case 2:
|
||||
pri_message(ctrl, "%c Informational frame:\n", direction_tag);
|
||||
break;
|
||||
case 1:
|
||||
type = "RNR (receive not ready)";
|
||||
pri_message(ctrl, "%c Supervisory frame:\n", direction_tag);
|
||||
break;
|
||||
case 2:
|
||||
type = "REJ (reject)";
|
||||
case 3:
|
||||
pri_message(ctrl, "%c Unnumbered frame:\n", direction_tag);
|
||||
break;
|
||||
}
|
||||
pri_message(ctrl, "%c Zero: %d S: %d 01: %d [ %s ]\n",
|
||||
|
||||
pri_message(ctrl, "%c SAPI: %02d C/R: %d EA: %d\n",
|
||||
direction_tag,
|
||||
h->s.x0,
|
||||
h->s.ss,
|
||||
h->s.ft,
|
||||
type);
|
||||
pri_message(ctrl, "%c N(R): %03d P/F: %d\n",
|
||||
h->h.sapi,
|
||||
h->h.c_r,
|
||||
h->h.ea1);
|
||||
pri_message(ctrl, "%c TEI: %03d EA: %d\n",
|
||||
direction_tag,
|
||||
h->s.n_r,
|
||||
h->s.p_f);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 4);
|
||||
break;
|
||||
case 3:
|
||||
/* Unnumbered frame */
|
||||
type = "???";
|
||||
if (h->u.ft == 3) {
|
||||
switch (h->u.m3) {
|
||||
h->h.tei,
|
||||
h->h.ea2);
|
||||
|
||||
switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
|
||||
case 0:
|
||||
case 2:
|
||||
/* Informational frame */
|
||||
pri_message(ctrl, "%c N(S): %03d 0: %d\n",
|
||||
direction_tag,
|
||||
h->i.n_s,
|
||||
h->i.ft);
|
||||
pri_message(ctrl, "%c N(R): %03d P: %d\n",
|
||||
direction_tag,
|
||||
h->i.n_r,
|
||||
h->i.p_f);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 4);
|
||||
break;
|
||||
case 1:
|
||||
/* Supervisory frame */
|
||||
type = "???";
|
||||
switch (h->s.ss) {
|
||||
case 0:
|
||||
if (h->u.m2 == 3)
|
||||
type = "DM (disconnect mode)";
|
||||
else if (h->u.m2 == 0)
|
||||
type = "UI (unnumbered information)";
|
||||
type = "RR (receive ready)";
|
||||
break;
|
||||
case 1:
|
||||
type = "RNR (receive not ready)";
|
||||
break;
|
||||
case 2:
|
||||
if (h->u.m2 == 0)
|
||||
type = "DISC (disconnect)";
|
||||
break;
|
||||
case 3:
|
||||
if (h->u.m2 == 3)
|
||||
type = "SABME (set asynchronous balanced mode extended)";
|
||||
else if (h->u.m2 == 0)
|
||||
type = "UA (unnumbered acknowledgement)";
|
||||
break;
|
||||
case 4:
|
||||
if (h->u.m2 == 1)
|
||||
type = "FRMR (frame reject)";
|
||||
break;
|
||||
case 5:
|
||||
if (h->u.m2 == 3)
|
||||
type = "XID (exchange identification note)";
|
||||
break;
|
||||
default:
|
||||
type = "REJ (reject)";
|
||||
break;
|
||||
}
|
||||
pri_message(ctrl, "%c Zero: %d S: %d 01: %d [ %s ]\n",
|
||||
direction_tag,
|
||||
h->s.x0,
|
||||
h->s.ss,
|
||||
h->s.ft,
|
||||
type);
|
||||
pri_message(ctrl, "%c N(R): %03d P/F: %d\n",
|
||||
direction_tag,
|
||||
h->s.n_r,
|
||||
h->s.p_f);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 4);
|
||||
break;
|
||||
case 3:
|
||||
/* Unnumbered frame */
|
||||
type = "???";
|
||||
if (h->u.ft == 3) {
|
||||
switch (h->u.m3) {
|
||||
case 0:
|
||||
if (h->u.m2 == 3)
|
||||
type = "DM (disconnect mode)";
|
||||
else if (h->u.m2 == 0)
|
||||
type = "UI (unnumbered information)";
|
||||
break;
|
||||
case 2:
|
||||
if (h->u.m2 == 0)
|
||||
type = "DISC (disconnect)";
|
||||
break;
|
||||
case 3:
|
||||
if (h->u.m2 == 3)
|
||||
type = "SABME (set asynchronous balanced mode extended)";
|
||||
else if (h->u.m2 == 0)
|
||||
type = "UA (unnumbered acknowledgement)";
|
||||
break;
|
||||
case 4:
|
||||
if (h->u.m2 == 1)
|
||||
type = "FRMR (frame reject)";
|
||||
break;
|
||||
case 5:
|
||||
if (h->u.m2 == 3)
|
||||
type = "XID (exchange identification note)";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
pri_message(ctrl, "%c M3: %d P/F: %d M2: %d 11: %d [ %s ]\n",
|
||||
direction_tag,
|
||||
h->u.m3,
|
||||
h->u.p_f,
|
||||
h->u.m2,
|
||||
h->u.ft,
|
||||
type);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 3);
|
||||
break;
|
||||
}
|
||||
pri_message(ctrl, "%c M3: %d P/F: %d M2: %d 11: %d [ %s ]\n",
|
||||
direction_tag,
|
||||
h->u.m3,
|
||||
h->u.p_f,
|
||||
h->u.m2,
|
||||
h->u.ft,
|
||||
type);
|
||||
pri_message(ctrl, "%c %d bytes of data\n",
|
||||
direction_tag,
|
||||
len - 3);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((h->u.ft == 3) && (h->u.m3 == 0) && (h->u.m2 == 0) && (h->u.data[0] == 0x0f)) {
|
||||
int ri;
|
||||
u_int8_t *action;
|
||||
|
||||
/* TEI management related */
|
||||
type = q921_tei_mgmt2str(h->u.data[3]);
|
||||
pri_message(ctrl, "%c MDL Message: %d(%s)\n", direction_tag, h->u.data[3], type);
|
||||
ri = (h->u.data[1] << 8) | h->u.data[2];
|
||||
pri_message(ctrl, "%c Ri: %d\n", direction_tag, ri);
|
||||
action = &h->u.data[4];
|
||||
for (x = len - (action - (u_int8_t *) h); 0 < x; --x, ++action) {
|
||||
pri_message(ctrl, "%c Ai: %d E:%d\n",
|
||||
direction_tag, (*action >> 1) & 0x7f, *action & 0x01);
|
||||
|
||||
if ((h->u.ft == 3) && (h->u.m3 == 0) && (h->u.m2 == 0) && (h->u.data[0] == 0x0f)) {
|
||||
int ri;
|
||||
u_int8_t *action;
|
||||
|
||||
/* TEI management related */
|
||||
type = q921_tei_mgmt2str(h->u.data[3]);
|
||||
pri_message(ctrl, "%c MDL Message: %d(%s)\n", direction_tag, h->u.data[3], type);
|
||||
ri = (h->u.data[1] << 8) | h->u.data[2];
|
||||
pri_message(ctrl, "%c Ri: %d\n", direction_tag, ri);
|
||||
action = &h->u.data[4];
|
||||
for (x = len - (action - (u_int8_t *) h); 0 < x; --x, ++action) {
|
||||
pri_message(ctrl, "%c Ai: %d E:%d\n",
|
||||
direction_tag, (*action >> 1) & 0x7f, *action & 0x01);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1409,8 +1484,20 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len)
|
||||
int tei;
|
||||
|
||||
if (!BRI_NT_PTMP(ctrl) && !BRI_TE_PTMP(ctrl)) {
|
||||
return pri_mkerror(ctrl,
|
||||
"Received MDL/TEI managemement message, but configured for mode other than PTMP!\n");
|
||||
/*
|
||||
* Some telco switches send out MDL messages even though they
|
||||
* are configured for PTP. Usually they are checking for
|
||||
* assigned TEI's.
|
||||
*/
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
/*
|
||||
* Send out this message in debug modes since it is possible the
|
||||
* user has misconfigured their link for the wrong mode.
|
||||
*/
|
||||
pri_message(ctrl, "Not configured for PTMP. Ignoring MDL message: %d(%s)\n",
|
||||
h->data[3], q921_tei_mgmt2str(h->data[3]));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
@@ -1471,12 +1558,13 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len)
|
||||
if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
|
||||
pri_message(ctrl, "Allocating new TEI %d\n", tei);
|
||||
}
|
||||
sub->next = pri_link_new(ctrl, Q921_SAPI_CALL_CTRL, tei);
|
||||
if (!sub->next) {
|
||||
link = pri_link_new(ctrl, Q921_SAPI_CALL_CTRL, tei);
|
||||
if (!link) {
|
||||
pri_error(ctrl, "Unable to allocate layer 2 link for new TEI %d\n", tei);
|
||||
return NULL;
|
||||
}
|
||||
q921_setstate(sub->next, Q921_TEI_ASSIGNED);
|
||||
sub->next = link;
|
||||
q921_setstate(link, Q921_TEI_ASSIGNED);
|
||||
q921_send_tei(ctrl, Q921_TEI_IDENTITY_ASSIGNED, ri, tei, 1);
|
||||
|
||||
count = 0;
|
||||
@@ -1493,6 +1581,15 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len)
|
||||
}
|
||||
q921_tei_check(ctrl);
|
||||
}
|
||||
|
||||
if (ctrl->l2_persistence == PRI_L2_PERSISTENCE_KEEP_UP) {
|
||||
/*
|
||||
* Layer 2 is persistent so give the peer some time to setup
|
||||
* it's new TEI and bring the link up itself before we bring the
|
||||
* link up.
|
||||
*/
|
||||
restart_timer_start(link);
|
||||
}
|
||||
break;
|
||||
case Q921_TEI_IDENTITY_CHECK_RESPONSE:
|
||||
if (!BRI_NT_PTMP(ctrl)) {
|
||||
@@ -1562,7 +1659,12 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len)
|
||||
|
||||
switch (link->state) {
|
||||
case Q921_TEI_UNASSIGNED:
|
||||
/* We do not have a TEI and we are not asking for one. */
|
||||
/*
|
||||
* We do not have a TEI and we are not currently asking for one.
|
||||
* Start asking for one.
|
||||
*/
|
||||
q921_setstate(link, Q921_ASSIGN_AWAITING_TEI);
|
||||
q921_tei_request(link);
|
||||
return NULL;
|
||||
case Q921_ASSIGN_AWAITING_TEI:
|
||||
case Q921_ESTABLISH_AWAITING_TEI:
|
||||
@@ -1604,9 +1706,12 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len)
|
||||
switch (link->state) {
|
||||
case Q921_ASSIGN_AWAITING_TEI:
|
||||
q921_setstate(link, Q921_TEI_ASSIGNED);
|
||||
ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP;
|
||||
res = &ctrl->ev;
|
||||
break;
|
||||
if (ctrl->l2_persistence != PRI_L2_PERSISTENCE_KEEP_UP) {
|
||||
ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP;
|
||||
res = &ctrl->ev;
|
||||
break;
|
||||
}
|
||||
/* Fall through: Layer 2 is persistent so bring it up. */
|
||||
case Q921_ESTABLISH_AWAITING_TEI:
|
||||
q921_establish_data_link(link);
|
||||
link->l3_initiated = 1;
|
||||
@@ -1765,7 +1870,7 @@ static pri_event *q921_disc_rx(struct q921_link *link, q921_h *h)
|
||||
break;
|
||||
case Q921_MULTI_FRAME_ESTABLISHED:
|
||||
case Q921_TIMER_RECOVERY:
|
||||
res = q921_ptp_delay_restart(link);
|
||||
res = q921_check_delay_restart(link);
|
||||
q921_discard_iqueue(link);
|
||||
q921_send_ua(link, h->u.p_f);
|
||||
/* DL-RELEASE indication */
|
||||
@@ -2177,7 +2282,7 @@ static pri_event *q921_ua_rx(struct q921_link *link, q921_h *h)
|
||||
if (!h->u.p_f) {
|
||||
q921_mdl_error(link, 'D');
|
||||
} else {
|
||||
res = q921_ptp_delay_restart(link);
|
||||
res = q921_check_delay_restart(link);
|
||||
/* DL-RELEASE confirm */
|
||||
q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
|
||||
stop_t200(link);
|
||||
@@ -2615,7 +2720,7 @@ static pri_event *q921_dm_rx(struct q921_link *link, q921_h *h)
|
||||
if (!h->u.p_f)
|
||||
break;
|
||||
|
||||
res = q921_ptp_delay_restart(link);
|
||||
res = q921_check_delay_restart(link);
|
||||
q921_discard_iqueue(link);
|
||||
/* DL-RELEASE indication */
|
||||
q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
|
||||
@@ -2625,7 +2730,7 @@ static pri_event *q921_dm_rx(struct q921_link *link, q921_h *h)
|
||||
case Q921_AWAITING_RELEASE:
|
||||
if (!h->u.p_f)
|
||||
break;
|
||||
res = q921_ptp_delay_restart(link);
|
||||
res = q921_check_delay_restart(link);
|
||||
/* DL-RELEASE confirm */
|
||||
q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
|
||||
stop_t200(link);
|
||||
@@ -2917,7 +3022,7 @@ static pri_event *__q921_receive(struct pri *ctrl, q921_h *h, int len)
|
||||
len -= 2;
|
||||
|
||||
if (ctrl->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW)) {
|
||||
q921_dump(ctrl, h, len, ctrl->debug & PRI_DEBUG_Q921_RAW, 0);
|
||||
q921_dump(ctrl, h, len, ctrl->debug, 0);
|
||||
}
|
||||
|
||||
/* Check some reject conditions -- Start by rejecting improper ea's */
|
||||
|
||||
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