Compare commits

..

51 Commits
0.6.0 ... 1.0.1

Author SHA1 Message Date
Kevin P. Fleming
e08d4abace remove CVS ignore lists
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.1@267 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 18:40:06 +00:00
Kevin P. Fleming
5c1f03b900 remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.1@266 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-29 18:39:18 +00:00
Kevin P. Fleming
7171c2179e automatic tag renames
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/1.0.1@263 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2005-11-27 04:17:23 +00:00
Admin Commit
0756477169 This commit was manufactured by cvs2svn to create tag 'v1-0-1'.
git-svn-id: https://origsvn.digium.com/svn/libpri/tags/v1-0-1@137 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-20 13:29:37 +00:00
Mark Spencer
2b7b7e2e68 Make sure retranstimer is set to 0
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@135 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-20 13:29:37 +00:00
Mark Spencer
9682be31fb Merge BKW's ANI2 patch (bug #2450)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@134 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-17 04:02:16 +00:00
Mark Spencer
ea146a8f6f Check for existance of *caller* number when sending caller, not called number (bug #2453)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@133 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-09-16 20:38:13 +00:00
Mark Spencer
12155fa6c3 Minor Makefile fixes for libpri (bug #2330)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@132 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-08-31 17:40:59 +00:00
Mark Spencer
96535a0c17 Fix redirecting number (bug #2146)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@131 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-08-25 06:20:50 +00:00
Mark Spencer
cac414333f Matt's requested fix
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@130 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-23 16:20:06 +00:00
Mark Spencer
748702c5c5 Don't seg when out of memory (bug #2120)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@129 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-23 16:04:01 +00:00
Mark Spencer
6dd859f5de Don't process subchannels by default
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@128 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-07-16 02:14:04 +00:00
Mark Spencer
5fd79b6b1b Add notify patch (bug #1785)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@127 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 17:57:18 +00:00
James Golovich
e88ac71b3d Make mkdep throw away stderr
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@126 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 15:19:15 +00:00
Mark Spencer
5166adfb1e Never send channel identifier with SETUP when GR303 CPE
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@125 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-29 04:28:34 +00:00
Mark Spencer
f8b7c404a0 Don't expect connect acknowledge on CPE when GR-303 mode
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@124 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-27 20:29:53 +00:00
Mark Spencer
b93317f38b Make sure NSF is initialized properly
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@123 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-26 04:42:20 +00:00
Mark Spencer
18958fa7e8 Add NSF support (bug #1927)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@122 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-26 04:37:09 +00:00
Mark Spencer
c9bb969586 Add subaddress support
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@121 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-25 19:33:12 +00:00
Mark Spencer
7cdd6c7f2c Don't send Character set in EuroISDN
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@120 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-24 13:43:36 +00:00
Mark Spencer
3193d779ef Don't change states on progress!
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@119 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-17 16:24:10 +00:00
Mark Spencer
97648bb1b4 Handle DISC and REL with missing mandatory information elements
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@118 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 22:19:11 +00:00
Mark Spencer
20e146406b More codeset fixes (thanks to pcadach)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@117 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 18:25:35 +00:00
Mark Spencer
1e5fad5fe7 Don't send proceeding when sending progress
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@116 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 18:04:22 +00:00
Mark Spencer
dd9ba5b8a5 Allow number complete to be forced on SETUP
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@115 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 17:16:37 +00:00
Mark Spencer
d4eab6216e Create new, more extensible setup method (pri_setup)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@114 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-16 15:33:58 +00:00
Mark Spencer
1cabafb5fb Handle locking and non-locking shift (bug #1687)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@113 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 22:21:05 +00:00
Mark Spencer
66781c3141 Separate PROGRESS and PROCEEDING
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@112 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 21:25:41 +00:00
Mark Spencer
832475b271 Debug improvements (including bug #1784)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@111 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 03:29:19 +00:00
Mark Spencer
6ccb8df101 Add notify support courtesy PCadach
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@110 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-14 02:48:24 +00:00
Mark Spencer
fd0f41e4a5 Include DS1 number
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@109 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 19:28:14 +00:00
James Golovich
0933575a5d Make q931.c:dump_display build the string first then print it in one command. Fixes remote console ugliness
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@108 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 06:51:01 +00:00
Mark Spencer
818a8cb57a Apprently AT&T uses 0x43 for maintenance messages too
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@107 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-10 03:57:43 +00:00
Mark Spencer
de0e6ba4cc Formatting fixes
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@106 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 17:00:29 +00:00
Mark Spencer
30d983f45f More GR-303 fixes, detect drop of D-channel
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@105 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 15:55:39 +00:00
Mark Spencer
d0c78dd62d Add the ability to slave one PRI to another with respect to calls
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@104 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-07 03:33:51 +00:00
Mark Spencer
551f0fafc8 Be careful not to destroy non-existant calls
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@103 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-06 23:26:43 +00:00
Mark Spencer
2300f57294 GR-303 updates
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@102 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-06 01:21:41 +00:00
Mark Spencer
f065327cc1 Major changes in preparation for GR-303 and NFAS support
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@101 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-06-05 06:50:55 +00:00
Mark Spencer
bce8bfb87f Fix minor typo (bug #1701)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@100 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-22 19:06:54 +00:00
Mark Spencer
4ae8cc7bcf Make build on FreeBSD
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@99 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-22 04:25:53 +00:00
Mark Spencer
76955b74c3 Properly handle non-transmission of channel identifier
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@98 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-20 00:21:16 +00:00
Mark Spencer
baefdcb18d Fix debugging of calling party number when no presentation specified (bug #1677)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@97 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 22:02:40 +00:00
Mark Spencer
7aac157b7f Only send channel identifier with call proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@96 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 21:01:36 +00:00
Mark Spencer
2c26d98a89 Add separate ability to do both progress and proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@95 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:34:43 +00:00
Mark Spencer
c413151375 Send progress indicator on progress if appropriate
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@94 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:26:16 +00:00
Mark Spencer
8098266c90 Allow progress to be sent with 1
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@93 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 15:21:15 +00:00
Mark Spencer
c8528b633a Allow ability to send just call proceeding
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@92 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-19 14:34:29 +00:00
Mark Spencer
c591726079 We have to update n_r when transmitting backlogged packets
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@91 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-05-17 03:32:11 +00:00
James Golovich
9f724a22f3 Extremely minor q931.c code cleanup
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@90 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-21 21:21:29 +00:00
Mark Spencer
c39fdd5cad On EuroISDN don't send layer1/2 since some switches seem to be concerned. (bug #960)
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@89 2fbb986a-6c06-0410-b554-c9c1f0a7f128
2004-04-16 18:05:41 +00:00
13 changed files with 1199 additions and 298 deletions

View File

@@ -27,6 +27,9 @@
# Uncomment if you want libpri to count number of Q921/Q931 sent/received
#LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
OSARCH=$(shell uname -s)
PROC=$(shell uname -m)
TOBJS=testpri.o
T2OBJS=testprilib.o
STATIC_LIBRARY=libpri.a
@@ -35,6 +38,22 @@ STATIC_OBJS=pri.o q921.o prisched.o q931.o
DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
INSTALL_PREFIX=
ifeq (${OSARCH},Linux)
LDCONFIG_FLAGS=-n
else
ifeq (${OSARCH},FreeBSD)
LDCONFIG_FLAGS=-m
CFLAGS += -I../zaptel -I../zapata
endif
endif
#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
#This works for even old (2.96) versions of gcc and provides a small boost either way.
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesnt support it.
ifeq ($(PROC),sparc64)
PROC=ultrasparc
CFLAGS += -mtune=$(PROC) -O3 -pipe -fomit-frame-pointer -mcpu=v8
endif
all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
@@ -59,16 +78,16 @@ uninstall:
rm -f $(INSTALL_PREFIX)/usr/include/libpri.h
pritest: pritest.o
$(CC) -o pritest pritest.o -L. -lpri -lzap
$(CC) -o pritest pritest.o -L. -lpri -lzap $(CFLAGS)
testprilib.o: testprilib.c
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE -o $@ -c $<
testprilib: testprilib.o
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
pridump: pridump.o
$(CC) -o pridump pridump.o -L. -lpri -lzap
$(CC) -o pridump pridump.o -L. -lpri -lzap $(CFLAGS)
include .depend
@@ -81,7 +100,7 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
$(CC) -shared -Wl,-soname,libpri.so.1 -o $@ $(DYNAMIC_OBJS)
/sbin/ldconfig -n .
/sbin/ldconfig $(LDCONFIG_FLAGS) .
ln -sf libpri.so.1 libpri.so
clean:

105
libpri.h
View File

@@ -49,6 +49,10 @@
#define PRI_SWITCH_EUROISDN_E1 5 /* Standard EuroISDN (CTR4, ETSI 300-102) */
#define PRI_SWITCH_EUROISDN_T1 6 /* T1 EuroISDN variant (ETSI 300-102) */
#define PRI_SWITCH_NI1 7 /* National ISDN 1 */
#define PRI_SWITCH_GR303_EOC 8 /* GR-303 Embedded Operations Channel */
#define PRI_SWITCH_GR303_TMC 9 /* GR-303 Timeslot Management Channel */
/* Switchtypes 10 - 20 are reserved for internal use */
/* PRI D-Channel Events */
#define PRI_EVENT_DCHAN_UP 1 /* D-channel is up */
@@ -66,6 +70,8 @@
#define PRI_EVENT_PROCEEDING 13 /* When we get CALL_PROCEEDING or PROGRESS */
#define PRI_EVENT_SETUP_ACK 14 /* When we get SETUP_ACKNOWLEDGE */
#define PRI_EVENT_HANGUP_REQ 15 /* Requesting the higher layer to hangup */
#define PRI_EVENT_NOTIFY 16 /* Notification received */
#define PRI_EVENT_PROGRESS 17 /* When we get CALL_PROCEEDING or PROGRESS */
/* Simple states */
#define PRI_STATE_DOWN 0
@@ -180,8 +186,51 @@
#define PRI_LAYER_1_V120_RATE_ADAPT 0x28
#define PRI_LAYER_1_X31_RATE_ADAPT 0x29
/* Notifications */
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */
#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */
#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */
#define PRI_NOTIFY_CONF_ESTABLISHED 0x42 /* Conference established */
#define PRI_NOTIFY_CONF_DISCONNECTED 0x43 /* Conference disconnected */
#define PRI_NOTIFY_CONF_PARTY_ADDED 0x44 /* Other party added */
#define PRI_NOTIFY_CONF_ISOLATED 0x45 /* Isolated */
#define PRI_NOTIFY_CONF_REATTACHED 0x46 /* Reattached */
#define PRI_NOTIFY_CONF_OTHER_ISOLATED 0x47 /* Other party isolated */
#define PRI_NOTIFY_CONF_OTHER_REATTACHED 0x48 /* Other party reattached */
#define PRI_NOTIFY_CONF_OTHER_SPLIT 0x49 /* Other party split */
#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */
#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */
#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */
#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */
#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */
#define PRI_COPY_DIGITS_CALLED_NUMBER
/* Network Specific Facilities (AT&T) */
#define PRI_NSF_NONE -1
#define PRI_NSF_SID_PREFERRED 0xB1
#define PRI_NSF_ANI_PREFERRED 0xB2
#define PRI_NSF_SID_ONLY 0xB3
#define PRI_NSF_ANI_ONLY 0xB4
#define PRI_NSF_CALL_ASSOC_TSC 0xB9
#define PRI_NSF_NOTIF_CATSC_CLEARING 0xBA
#define PRI_NSF_OPERATOR 0xB5
#define PRI_NSF_PCCO 0xB6
#define PRI_NSF_SDN 0xE1
#define PRI_NSF_TOLL_FREE_MEGACOM 0xE2
#define PRI_NSF_MEGACOM 0xE3
#define PRI_NSF_ACCUNET 0xE6
#define PRI_NSF_LONG_DISTANCE_SERVICE 0xE7
#define PRI_NSF_INTERNATIONAL_TOLL_FREE 0xE8
#define PRI_NSF_ATT_MULTIQUEST 0xF0
#define PRI_NSF_CALL_REDIRECTION_SERVICE 0xF7
typedef struct q931_call q931_call;
typedef struct pri_event_generic {
@@ -230,6 +279,7 @@ typedef struct pri_event_ring {
char callingnum[256]; /* Calling number */
char callingname[256]; /* Calling name (if provided) */
int calledplan; /* Dialing plan of Called number */
int ani2; /* ANI II */
char callednum[256]; /* Called number */
char redirectingnum[256]; /* Redirecting number */
char useruserinfo[256]; /* User->User info */
@@ -239,6 +289,7 @@ typedef struct pri_event_ring {
int layer1; /* User layer 1 */
int complete; /* Have we seen "Complete" i.e. no more number? */
q931_call *call; /* Opaque call pointer */
char callingsubaddr[256]; /* Calling parties subaddress */
} pri_event_ring;
typedef struct pri_event_hangup {
@@ -264,6 +315,12 @@ typedef struct pri_event_setup_ack {
int channel;
} pri_event_setup_ack;
typedef struct pri_event_notify {
int e;
int channel;
int info;
} pri_event_notify;
typedef union {
int e;
pri_event_generic gen; /* Generic view */
@@ -277,9 +334,11 @@ typedef union {
pri_event_restart_ack restartack; /* Restart Acknowledge */
pri_event_proceeding proceeding; /* Call proceeding & Progress */
pri_event_setup_ack setup_ack; /* SETUP_ACKNOWLEDGE structure */
pri_event_notify notify; /* Notification */
} pri_event;
struct pri;
struct pri_sr;
/* Create a D-channel on a given file descriptor. The file descriptor must be a
@@ -288,6 +347,9 @@ struct pri;
must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */
extern struct pri *pri_new(int fd, int nodetype, int switchtype);
/* Set Network Specific Facility for PRI */
extern void pri_set_nsf(struct pri *pri, int nsf);
/* Set debug parameters on PRI -- see above debug definitions */
extern void pri_set_debug(struct pri *pri, int debug);
@@ -338,14 +400,8 @@ extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
#if 0
/* deprecated routines, use pri_hangup */
/* Release/Reject a call */
extern int pri_release(struct pri *pri, q931_call *call, int cause);
/* Set CRV reference for GR-303 calls */
/* Hangup / Disconnect a call */
extern int pri_disconnect(struct pri *pri, q931_call *call, int cause);
#endif
#undef pri_release
#undef pri_disconnect
@@ -369,6 +425,12 @@ extern int pri_reset(struct pri *pri, int channel);
/* Create a new call */
extern q931_call *pri_new_call(struct pri *pri);
/* Retrieve CRV reference for GR-303 calls. Returns >0 on success. */
extern int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
/* Retrieve CRV reference for GR-303 calls. CRV must be >0, call mode should be 0 */
extern int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode);
/* How long until you need to poll for a new event */
extern struct timeval *pri_schedule_next(struct pri *pri);
@@ -378,6 +440,16 @@ extern pri_event *pri_schedule_run(struct pri *pri);
extern int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
char *called,int calledplan, int ulayer1);
extern struct pri_sr *pri_sr_new(void);
extern void pri_sr_free(struct pri_sr *sr);
extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
/* Override message and error stuff */
extern void pri_set_message(void (*__pri_error)(char *));
@@ -393,4 +465,23 @@ extern void pri_dump_info(struct pri *pri);
/* Get file descriptor */
extern int pri_fd(struct pri *pri);
#define PRI_PROGRESS
/* Send call proceeding */
extern int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
#define PRI_PROCEEDING_FULL
/* Send call proceeding */
extern int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
/* Enslave a PRI to another, so they share the same call list
(and maybe some timers) */
extern void pri_enslave(struct pri *master, struct pri *slave);
#define PRI_GR303_SUPPORT
#define PRI_ENSLAVE_SUPPORT
#define PRI_SETUP_CALL
#define PRI_RECEIVE_SUBADDR
#endif
/* Send notification */
extern int pri_notify(struct pri *pri, q931_call *c, int channel, int info);

4
mkdep
View File

@@ -82,9 +82,9 @@ umask $um
trap 'rm -rf $DTMP ; trap 2 ; kill -2 $$' 1 2 3 13 15
if [ x$pflag = x ]; then
${CC:-cc} -M "$@" | sed -e 's; \./; ;g' > $TMP
${CC:-cc} -M "$@" 2>/dev/null | sed -e 's; \./; ;g' > $TMP
else
${CC:-cc} -M "$@" | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
${CC:-cc} -M "$@" 2>/dev/null | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
fi
if [ $? != 0 ]; then

165
pri.c
View File

@@ -53,12 +53,16 @@ char *pri_switch2str(int sw)
return "National ISDN 1";
case PRI_SWITCH_EUROISDN_E1:
return "EuroISDN";
case PRI_SWITCH_GR303_EOC:
return "GR303 EOC";
case PRI_SWITCH_GR303_TMC:
return "GR303 TMC";
default:
return "Unknown switchtype";
}
}
struct pri *pri_new(int fd, int node, int switchtype)
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master)
{
struct pri *p;
p = malloc(sizeof(struct pri));
@@ -68,18 +72,63 @@ struct pri *pri_new(int fd, int node, int switchtype)
p->localtype = node;
p->switchtype = switchtype;
p->cref = 1;
p->sapi = Q921_SAPI_CALL_CTRL;
p->tei = 0;
p->nsf = PRI_NSF_NONE;
p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
p->master = master;
p->callpool = &p->localpool;
#ifdef LIBPRI_COUNTERS
p->q921_rxcount = 0;
p->q921_txcount = 0;
p->q931_rxcount = 0;
p->q931_txcount = 0;
#endif
if (switchtype == PRI_SWITCH_GR303_EOC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_OPS;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p);
if (!p->subchannel) {
free(p);
p = NULL;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
p->tei = Q921_TEI_GR303_TMC_CALLPROC;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p);
if (!p->subchannel) {
free(p);
p = NULL;
}
} else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
p->tei = Q921_TEI_GR303_TMC_SWITCHING;
} else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_PATH;
}
/* Start Q.921 layer, Wait if we're the network */
q921_start(p, p->localtype == PRI_CPE);
if (p)
q921_start(p, p->localtype == PRI_CPE);
}
return p;
}
struct pri *pri_new(int fd, int node, int switchtype)
{
return __pri_new(fd, node, switchtype, NULL);
}
void pri_set_nsf(struct pri *pri, int nsf)
{
if (pri)
pri->nsf = nsf;
}
char *pri_event2str(int id)
{
switch(id) {
@@ -182,6 +231,8 @@ void pri_set_debug(struct pri *pri, int debug)
if (!pri)
return;
pri->debug = debug;
if (pri->subchannel)
pri_set_debug(pri->subchannel, debug);
}
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
@@ -191,6 +242,20 @@ int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
return q931_alerting(pri, call, channel, info);
}
int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_call_proceeding(pri, call, channel, info);
}
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_call_progress(pri, call, channel, info);
}
int pri_information(struct pri *pri, q931_call *call, char digit)
{
if (!pri || !call)
@@ -198,6 +263,13 @@ int pri_information(struct pri *pri, q931_call *call, char digit)
return q931_information(pri, call, digit);
}
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
return q931_notify(pri, call, channel, info);
}
void pri_destroycall(struct pri *pri, q931_call *call)
{
if (pri && call)
@@ -287,13 +359,39 @@ void pri_dump_event(struct pri *pri, pri_event *e)
}
}
static void pri_sr_init(struct pri_sr *req)
{
memset(req, 0, sizeof(struct pri_sr));
}
int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
{
if (!pri || !c)
return -1;
return q931_setup(pri, c, req);
}
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called,
int calledplan,int ulayer1)
{
struct pri_sr req;
if (!pri || !c)
return -1;
return q931_setup(pri, c, transmode, channel, exclusive, nonisdn, caller, callerplan, callername, callerpres, called, calledplan, ulayer1);
pri_sr_init(&req);
req.transmode = transmode;
req.channel = channel;
req.exclusive = exclusive;
req.nonisdn = nonisdn;
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
req.userl1 = ulayer1;
return q931_setup(pri, c, &req);
}
static void (*__pri_error)(char *stuff);
@@ -378,3 +476,64 @@ void pri_dump_info(struct pri *pri)
pri_message("Overlap Dial: %d\n", pri->overlapdial);
}
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode)
{
return q931_call_getcrv(pri, call, callmode);
}
int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode)
{
return q931_call_setcrv(pri, call, crv, callmode);
}
void pri_enslave(struct pri *master, struct pri *slave)
{
if (master && slave)
slave->callpool = &master->localpool;
}
struct pri_sr *pri_sr_new(void)
{
struct pri_sr *req;
req = malloc(sizeof(struct pri_sr));
if (req)
pri_sr_init(req);
return req;
}
void pri_sr_free(struct pri_sr *sr)
{
free(sr);
}
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn)
{
sr->channel = channel;
sr->exclusive = exclusive;
sr->nonisdn = nonisdn;
return 0;
}
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1)
{
sr->transmode = transmode;
sr->userl1 = userl1;
return 0;
}
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int numcomplete)
{
sr->called = called;
sr->calledplan = calledplan;
sr->numcomplete = numcomplete;
return 0;
}
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
{
sr->caller = caller;
sr->callername = callername;
sr->callerplan = callerplan;
sr->callerpres = callerpres;
return 0;
}

View File

@@ -42,12 +42,19 @@ enum q931_mode;
struct pri {
int fd; /* File descriptor for D-Channel */
struct pri *subchannel; /* Sub-channel if appropriate */
struct pri *master; /* Master channel if appropriate */
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */
int debug; /* Debug stuff */
int state; /* State of D-channel */
int switchtype; /* Switch type */
int nsf; /* Network-Specific Facility (if any) */
int localtype; /* Local network type (unknown, network, cpe) */
int remotetype; /* Remote network type (unknown, network, cpe) */
int sapi;
int tei;
int protodisc;
/* Q.921 State */
int q921_state;
@@ -79,7 +86,8 @@ struct pri {
struct q921_frame *txqueue;
/* Q.931 calls */
q931_call *calls;
q931_call **callpool;
q931_call *localpool;
/* do we do overlap dialing */
int overlapdial;
@@ -93,6 +101,25 @@ struct pri {
#endif
};
struct pri_sr {
int transmode;
int channel;
int exclusive;
int nonisdn;
char *caller;
int callerplan;
char *callername;
int callerpres;
char *called;
int calledplan;
int userl1;
int numcomplete;
};
/* Internal switch types */
#define PRI_SWITCH_GR303_EOC_PATH 10
#define PRI_SWITCH_GR303_TMC_SWITCHING 11
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
extern pri_event *pri_schedule_run(struct pri *pri);

View File

@@ -26,7 +26,11 @@
#define _PRI_Q921_H
#include <sys/types.h>
#if defined(__linux__)
#include <endian.h>
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#endif
/* Timer values */
@@ -43,8 +47,17 @@
#define Q921_FRAMETYPE_S 0x1
#define Q921_TEI_GROUP 127
#define Q921_TEI_GR303_EOC_PATH 0
#define Q921_TEI_GR303_EOC_OPS 4
#define Q921_TEI_GR303_TMC_SWITCHING 0
#define Q921_TEI_GR303_TMC_CALLPROC 0
#define Q921_SAPI_CALL_CTRL 0
#define Q921_SAPI_GR303_EOC 1
#define Q921_SAPI_GR303_TMC_SWITCHING 1
#define Q921_SAPI_GR303_TMC_CALLPROC 0
#define Q921_SAPI_CALL_CTRL 0
#define Q921_SAPI_PACKET_MODE 1
#define Q921_SAPI_X25_LAYER3 16
#define Q921_SAPI_LAYER2_MANAGEMENT 63

View File

@@ -98,13 +98,7 @@ typedef struct q931_mh {
/* Information element format */
typedef struct q931_ie {
#if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t f:1;
u_int8_t ie:7;
#else
u_int8_t ie:7;
u_int8_t f:1;
#endif
u_int8_t ie;
u_int8_t len;
u_int8_t data[0];
} q931_ie;
@@ -113,6 +107,7 @@ typedef struct q931_ie {
#define Q931_RES_INERRROR (1 << 1)
#define Q931_PROTOCOL_DISCRIMINATOR 0x08
#define GR303_PROTOCOL_DISCRIMINATOR 0x4f
/* Q.931 / National ISDN Message Types */
@@ -165,6 +160,7 @@ typedef struct q931_ie {
/* Q.931 / National ISDN Information Elements */
#define Q931_LOCKING_SHIFT 0x90
#define Q931_NON_LOCKING_SHIFT 0x98
#define Q931_BEARER_CAPABILITY 0x04
#define Q931_CAUSE 0x08
#define Q931_CALL_STATE 0x14
@@ -190,10 +186,17 @@ typedef struct q931_ie {
#define Q931_LOW_LAYER_COMPAT 0x7c
#define Q931_HIGH_LAYER_COMPAT 0x7d
#define Q931_CODESET(x) ((x) << 8)
#define Q931_IE_CODESET(x) ((x) >> 8)
#define Q931_IE_IE(x) ((x) & 0xff)
#define Q931_FULL_IE(codeset, ie) (((codeset) << 8) | ((ie) & 0xff))
#define Q931_DISPLAY 0x28
#define Q931_IE_SEGMENTED_MSG 0x00
#define Q931_IE_CHANGE_STATUS 0x01
#define Q931_IE_CONNECTED_NUM 0x0C
#define Q931_IE_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
#define Q931_IE_CONNECTED_ADDR 0x0C
#define Q931_IE_CONNECTED_NUM 0x4C
#define Q931_IE_CALL_IDENTITY 0x10
#define Q931_IE_FACILITY 0x1c
#define Q931_IE_ENDPOINT_ID 0x26
@@ -237,13 +240,17 @@ typedef struct q931_ie {
/* EuroISDN */
#define Q931_SENDING_COMPLETE 0x21
#define Q931_SENDING_COMPLETE 0xa1
extern int q931_receive(struct pri *pri, q931_h *h, int len);
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_call_proceeding(struct pri *pri, q931_call *call);
extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
@@ -259,11 +266,13 @@ extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
extern int q931_restart(struct pri *pri, int channel);
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);
extern q931_call *q931_new_call(struct pri *pri);
extern int q931_setup(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called,
int calledplan, int ulay1);
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
extern void q931_dump(q931_h *h, int len, int txrx);
extern void __q931_destroycall(struct pri *pri, q931_call *c);

View File

@@ -36,7 +36,12 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include "libpri.h"
#include "pri_q921.h"
#include "pri_q931.h"

View File

@@ -60,6 +60,9 @@ struct timeval *pri_schedule_next(struct pri *pri)
{
struct timeval *closest = NULL;
int x;
/* Check subchannels */
if (pri->subchannel)
closest = pri_schedule_next(pri->subchannel);
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
(!closest || (closest->tv_sec > pri->pri_sched[x].when.tv_sec) ||
@@ -70,19 +73,23 @@ struct timeval *pri_schedule_next(struct pri *pri)
return closest;
}
pri_event *pri_schedule_run(struct pri *pri)
static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
{
struct timeval tv;
int x;
void (*callback)(void *);
void *data;
gettimeofday(&tv, NULL);
pri_event *e;
if (pri->subchannel) {
if ((e = __pri_schedule_run(pri->subchannel, tv))) {
return e;
}
}
for (x=1;x<MAX_SCHED;x++) {
if (pri->pri_sched[x].callback &&
((pri->pri_sched[x].when.tv_sec < tv.tv_sec) ||
((pri->pri_sched[x].when.tv_sec == tv.tv_sec) &&
(pri->pri_sched[x].when.tv_usec <= tv.tv_usec)))) {
pri->schedev = 0;
((pri->pri_sched[x].when.tv_sec < tv->tv_sec) ||
((pri->pri_sched[x].when.tv_sec == tv->tv_sec) &&
(pri->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
pri->schedev = 0;
callback = pri->pri_sched[x].callback;
data = pri->pri_sched[x].data;
pri->pri_sched[x].callback = NULL;
@@ -90,11 +97,19 @@ pri_event *pri_schedule_run(struct pri *pri)
callback(data);
if (pri->schedev)
return &pri->ev;
}
}
}
return NULL;
}
pri_event *pri_schedule_run(struct pri *pri)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return __pri_schedule_run(pri, &tv);
}
void pri_schedule_del(struct pri *pri,int id)
{
if ((id >= MAX_SCHED) || (id < 0))

View File

@@ -40,7 +40,11 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include "libpri.h"
@@ -116,6 +120,10 @@ static int str2switch(char *swtype)
return PRI_SWITCH_ATT4ESS;
if (!strcasecmp(swtype, "euroisdn"))
return PRI_SWITCH_EUROISDN_E1;
if (!strcasecmp(swtype, "gr303eoc"))
return PRI_SWITCH_GR303_EOC;
if (!strcasecmp(swtype, "gr303tmc"))
return PRI_SWITCH_GR303_TMC;
return -1;
}
@@ -295,6 +303,7 @@ static int run_pri(int dfd, int swtype, int node)
fprintf(stderr, "Unable to create PRI\n");
return -1;
}
pri_set_debug(pri, -1);
for (;;) {
/* Run the D-Channel */

102
q921.c
View File

@@ -41,12 +41,12 @@
#define RANDOM_DROPS
*/
#define Q921_INIT(hf) do { \
#define Q921_INIT(pri, hf) do { \
memset(&(hf),0,sizeof(hf)); \
(hf).h.sapi = 0; \
(hf).h.sapi = (pri)->sapi; \
(hf).h.ea1 = 0; \
(hf).h.ea2 = 1; \
(hf).h.tei = 0; \
(hf).h.tei = (pri)->tei; \
} while(0)
static void reschedule_t203(struct pri *pri);
@@ -67,6 +67,8 @@ static void q921_discard_retransmissions(struct pri *pri)
static int q921_transmit(struct pri *pri, q921_h *h, int len)
{
int res;
if (pri->master)
return q921_transmit(pri->master, h, len);
#ifdef RANDOM_DROPS
if (!(random() % 3)) {
pri_message(" === Dropping Packet ===\n");
@@ -92,7 +94,7 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
static void q921_send_ua(struct pri *pri, int pfbit)
{
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.u.m3 = 3; /* M3 = 3 */
h.u.m2 = 0; /* M2 = 0 */
h.u.p_f = pfbit; /* Final bit on */
@@ -124,7 +126,7 @@ static void q921_send_sabme(void *vpri, int now)
pri->sabme_timer = pri_schedule_event(pri, T_200, q921_send_sabme_now, pri);
if (!now)
return;
Q921_INIT(h);
Q921_INIT(pri, h);
h.u.m3 = 3; /* M3 = 3 */
h.u.m2 = 3; /* M2 = 3 */
h.u.p_f = 1; /* Poll bit set */
@@ -181,6 +183,7 @@ static int q921_ack_packet(struct pri *pri, int num)
pri_message("-- Finally transmitting %d, since window opened up\n", f->h.n_s);
f->transmitted++;
pri->windowlen++;
f->h.n_r = pri->v_r;
q921_transmit(pri, (q921_h *)(&f->h), f->len);
break;
}
@@ -218,7 +221,7 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
for (x=pri->v_a; (x != pri->v_s) && (x != ack); Q921_INC(x));
if (x != ack) {
/* ACK was outside of our window --- ignore */
pri_error("ACK received outside of window, restarting\n");
pri_error("ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a, pri->v_s);
ev = q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
@@ -260,7 +263,7 @@ static pri_event *q921_ack_rx(struct pri *pri, int ack)
static void q921_reject(struct pri *pri, int pf)
{
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.s.x0 = 0; /* Always 0 */
h.s.ss = 2; /* Reject */
h.s.ft = 1; /* Frametype (01) */
@@ -285,7 +288,7 @@ static void q921_reject(struct pri *pri, int pf)
static void q921_rr(struct pri *pri, int pbit, int cmd) {
q921_h h;
Q921_INIT(h);
Q921_INIT(pri, h);
h.s.x0 = 0; /* Always 0 */
h.s.ss = 0; /* Receive Ready */
h.s.ft = 1; /* Frametype (01) */
@@ -352,9 +355,26 @@ static void t200_expire(void *vpri)
q921_start(pri, 1);
pri->schedev = 1;
}
} else if (pri->solicitfbit) {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Retrying poll with f-bit\n");
pri->retrans++;
if (pri->retrans < N_200) {
pri->solicitfbit = 1;
q921_rr(pri, 1, 1);
pri->t200_timer = pri_schedule_event(pri, T_200, t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("-- Timeout occured, restarting PRI\n");
pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
pri->t200_timer = 0;
q921_dchannel_down(pri);
q921_start(pri, 1);
pri->schedev = 1;
}
} else {
pri_error("T200 counter expired, nothing to send...\n");
pri->t200_timer = 0;
pri->t200_timer = 0;
}
}
@@ -363,9 +383,9 @@ int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
q921_frame *f, *prev=NULL;
for (f=pri->txqueue; f; f = f->next) prev = f;
f = malloc(sizeof(q921_frame) + len + 2);
memset(f,0,sizeof(q921_frame) + len + 2);
if (f) {
Q921_INIT(f->h);
memset(f,0,sizeof(q921_frame) + len + 2);
Q921_INIT(pri, f->h);
switch(pri->localtype) {
case PRI_NETWORK:
if (cr)
@@ -436,12 +456,13 @@ static void t203_expire(void *vpri)
pri_message("T203 counter expired, sending RR and scheduling T203 again\n");
/* Solicit an F-bit in the other's RR */
pri->solicitfbit = 1;
pri->retrans = 0;
q921_rr(pri, 1, 1);
/* Restart ourselves */
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
/* Start timer T200 to resend our RR if we don't get it */
pri->t203_timer = pri_schedule_event(pri, T_200, t200_expire, pri);
} else {
if (pri->debug & PRI_DEBUG_Q921_STATE)
pri_message("T203 counter expired in weird statd %d\n", pri->q921_state);
pri_message("T203 counter expired in weird state %d\n", pri->q921_state);
pri->t203_timer = 0;
}
}
@@ -677,28 +698,11 @@ void q921_reset(struct pri *pri)
q921_discard_retransmissions(pri);
}
static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
{
q921_frame *f;
pri_event *ev;
int sendnow;
/* Discard FCS */
len -= 2;
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
/* Check some reject conditions -- Start by rejecting improper ea's */
if (h->h.ea1 || !(h->h.ea2))
return NULL;
/* Check for broadcasts - not yet handled */
if (h->h.tei == Q921_TEI_GROUP)
return NULL;
/* Check for SAPIs we don't yet handle */
if (h->h.sapi != Q921_SAPI_CALL_CTRL)
return NULL;
switch(h->h.data[0] & Q921_FRAMETYPE_MASK) {
case 0:
@@ -890,11 +894,43 @@ static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
return NULL;
}
static pri_event *__q921_receive(struct pri *pri, q921_h *h, int len)
{
pri_event *ev;
/* Discard FCS */
len -= 2;
if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
/* Check some reject conditions -- Start by rejecting improper ea's */
if (h->h.ea1 || !(h->h.ea2))
return NULL;
/* Check for broadcasts - not yet handled */
if (h->h.tei == Q921_TEI_GROUP)
return NULL;
/* Check for SAPIs we don't yet handle */
if ((h->h.sapi != pri->sapi) || (h->h.tei != pri->tei)) {
#ifdef PROCESS_SUBCHANNELS
/* If it's not us, try any subchannels we have */
if (pri->subchannel)
return q921_receive(pri->subchannel, h, len + 2);
else
#endif
return NULL;
}
ev = __q921_receive_qualified(pri, h, len);
reschedule_t203(pri);
return ev;
}
pri_event *q921_receive(struct pri *pri, q921_h *h, int len)
{
pri_event *e;
e = __q921_receive(pri, h, len);
reschedule_t203(pri);
#ifdef LIBPRI_COUNTERS
pri->q921_rxcount++;
#endif

966
q931.c

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,11 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#if defined(__linux__)
#include <linux/zaptel.h>
#elif defined(__FreeBSD__)
#include <zaptel.h>
#endif
#include <zap.h>
#include <pthread.h>
#include <sys/select.h>