Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
790e386bdd | ||
|
|
ac91b55cee | ||
|
|
42b8d8eb04 | ||
|
|
d85f96808b |
27
Makefile
27
Makefile
@@ -27,9 +27,6 @@
|
||||
# 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
|
||||
@@ -38,22 +35,6 @@ 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)
|
||||
|
||||
@@ -78,16 +59,16 @@ uninstall:
|
||||
rm -f $(INSTALL_PREFIX)/usr/include/libpri.h
|
||||
|
||||
pritest: pritest.o
|
||||
$(CC) -o pritest pritest.o -L. -lpri -lzap $(CFLAGS)
|
||||
$(CC) -o pritest pritest.o -L. -lpri -lzap
|
||||
|
||||
testprilib.o: testprilib.c
|
||||
$(CC) $(CFLAGS) -D_REENTRANT -D_GNU_SOURCE -o $@ -c $<
|
||||
|
||||
testprilib: testprilib.o
|
||||
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread $(CFLAGS)
|
||||
$(CC) -o testprilib testprilib.o -L. -lpri -lpthread
|
||||
|
||||
pridump: pridump.o
|
||||
$(CC) -o pridump pridump.o -L. -lpri -lzap $(CFLAGS)
|
||||
$(CC) -o pridump pridump.o -L. -lpri -lzap
|
||||
|
||||
include .depend
|
||||
|
||||
@@ -100,7 +81,7 @@ $(STATIC_LIBRARY): $(STATIC_OBJS)
|
||||
|
||||
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
|
||||
$(CC) -shared -Wl,-soname,libpri.so.1 -o $@ $(DYNAMIC_OBJS)
|
||||
/sbin/ldconfig $(LDCONFIG_FLAGS) .
|
||||
/sbin/ldconfig -n .
|
||||
ln -sf libpri.so.1 libpri.so
|
||||
|
||||
clean:
|
||||
|
||||
105
libpri.h
105
libpri.h
@@ -49,10 +49,6 @@
|
||||
#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 */
|
||||
@@ -70,8 +66,6 @@
|
||||
#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
|
||||
@@ -186,51 +180,8 @@
|
||||
#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 {
|
||||
@@ -279,7 +230,6 @@ 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 */
|
||||
@@ -289,7 +239,6 @@ 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 {
|
||||
@@ -315,12 +264,6 @@ 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 */
|
||||
@@ -334,11 +277,9 @@ 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
|
||||
@@ -347,9 +288,6 @@ struct pri_sr;
|
||||
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);
|
||||
|
||||
@@ -400,8 +338,14 @@ 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);
|
||||
|
||||
/* Set CRV reference for GR-303 calls */
|
||||
#if 0
|
||||
/* deprecated routines, use pri_hangup */
|
||||
/* Release/Reject a call */
|
||||
extern int pri_release(struct pri *pri, q931_call *call, int cause);
|
||||
|
||||
/* Hangup / Disconnect a call */
|
||||
extern int pri_disconnect(struct pri *pri, q931_call *call, int cause);
|
||||
#endif
|
||||
|
||||
#undef pri_release
|
||||
#undef pri_disconnect
|
||||
@@ -425,12 +369,6 @@ 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);
|
||||
|
||||
@@ -440,16 +378,6 @@ 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 *));
|
||||
@@ -465,23 +393,4 @@ 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
4
mkdep
@@ -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 "$@" 2>/dev/null | sed -e 's; \./; ;g' > $TMP
|
||||
${CC:-cc} -M "$@" | sed -e 's; \./; ;g' > $TMP
|
||||
else
|
||||
${CC:-cc} -M "$@" 2>/dev/null | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
|
||||
${CC:-cc} -M "$@" | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
|
||||
fi
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
|
||||
165
pri.c
165
pri.c
@@ -53,16 +53,12 @@ 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";
|
||||
}
|
||||
}
|
||||
|
||||
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master)
|
||||
struct pri *pri_new(int fd, int node, int switchtype)
|
||||
{
|
||||
struct pri *p;
|
||||
p = malloc(sizeof(struct pri));
|
||||
@@ -72,63 +68,18 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
|
||||
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 */
|
||||
if (p)
|
||||
q921_start(p, p->localtype == PRI_CPE);
|
||||
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) {
|
||||
@@ -231,8 +182,6 @@ 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)
|
||||
@@ -242,20 +191,6 @@ 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)
|
||||
@@ -263,13 +198,6 @@ 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)
|
||||
@@ -359,39 +287,13 @@ 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;
|
||||
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);
|
||||
return q931_setup(pri, c, transmode, channel, exclusive, nonisdn, caller, callerplan, callername, callerpres, called, calledplan, ulayer1);
|
||||
}
|
||||
|
||||
static void (*__pri_error)(char *stuff);
|
||||
@@ -476,64 +378,3 @@ 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;
|
||||
}
|
||||
|
||||
@@ -42,19 +42,12 @@ 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;
|
||||
@@ -86,8 +79,7 @@ struct pri {
|
||||
struct q921_frame *txqueue;
|
||||
|
||||
/* Q.931 calls */
|
||||
q931_call **callpool;
|
||||
q931_call *localpool;
|
||||
q931_call *calls;
|
||||
|
||||
/* do we do overlap dialing */
|
||||
int overlapdial;
|
||||
@@ -101,25 +93,6 @@ 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);
|
||||
|
||||
15
pri_q921.h
15
pri_q921.h
@@ -26,11 +26,7 @@
|
||||
#define _PRI_Q921_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
/* Timer values */
|
||||
|
||||
@@ -47,17 +43,8 @@
|
||||
#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
|
||||
|
||||
35
pri_q931.h
35
pri_q931.h
@@ -98,7 +98,13 @@ typedef struct q931_mh {
|
||||
|
||||
/* Information element format */
|
||||
typedef struct q931_ie {
|
||||
u_int8_t 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 len;
|
||||
u_int8_t data[0];
|
||||
} q931_ie;
|
||||
@@ -107,7 +113,6 @@ 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 */
|
||||
|
||||
@@ -160,7 +165,6 @@ 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
|
||||
@@ -186,17 +190,10 @@ 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_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
|
||||
#define Q931_IE_CONNECTED_ADDR 0x0C
|
||||
#define Q931_IE_CONNECTED_NUM 0x4C
|
||||
#define Q931_IE_CONNECTED_NUM 0x0C
|
||||
#define Q931_IE_CALL_IDENTITY 0x10
|
||||
#define Q931_IE_FACILITY 0x1c
|
||||
#define Q931_IE_ENDPOINT_ID 0x26
|
||||
@@ -240,17 +237,13 @@ typedef struct q931_ie {
|
||||
|
||||
|
||||
/* EuroISDN */
|
||||
#define Q931_SENDING_COMPLETE 0xa1
|
||||
#define Q931_SENDING_COMPLETE 0x21
|
||||
|
||||
extern int q931_receive(struct pri *pri, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
extern int q931_call_progress(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_call_proceeding(struct pri *pri, q931_call *call);
|
||||
|
||||
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||
|
||||
@@ -266,13 +259,11 @@ 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, struct pri_sr *req);
|
||||
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 void q931_dump(q931_h *h, int len, int txrx);
|
||||
|
||||
extern void __q931_destroycall(struct pri *pri, q931_call *c);
|
||||
|
||||
@@ -36,12 +36,7 @@
|
||||
#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"
|
||||
|
||||
31
prisched.c
31
prisched.c
@@ -60,9 +60,6 @@ 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) ||
|
||||
@@ -73,23 +70,19 @@ struct timeval *pri_schedule_next(struct pri *pri)
|
||||
return closest;
|
||||
}
|
||||
|
||||
static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
|
||||
pri_event *pri_schedule_run(struct pri *pri)
|
||||
{
|
||||
struct timeval tv;
|
||||
int x;
|
||||
void (*callback)(void *);
|
||||
void *data;
|
||||
pri_event *e;
|
||||
if (pri->subchannel) {
|
||||
if ((e = __pri_schedule_run(pri->subchannel, tv))) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
gettimeofday(&tv, NULL);
|
||||
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;
|
||||
@@ -97,19 +90,11 @@ static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
|
||||
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))
|
||||
|
||||
@@ -40,11 +40,7 @@
|
||||
#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"
|
||||
|
||||
@@ -120,10 +116,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -303,7 +295,6 @@ 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
102
q921.c
@@ -41,12 +41,12 @@
|
||||
#define RANDOM_DROPS
|
||||
*/
|
||||
|
||||
#define Q921_INIT(pri, hf) do { \
|
||||
#define Q921_INIT(hf) do { \
|
||||
memset(&(hf),0,sizeof(hf)); \
|
||||
(hf).h.sapi = (pri)->sapi; \
|
||||
(hf).h.sapi = 0; \
|
||||
(hf).h.ea1 = 0; \
|
||||
(hf).h.ea2 = 1; \
|
||||
(hf).h.tei = (pri)->tei; \
|
||||
(hf).h.tei = 0; \
|
||||
} while(0)
|
||||
|
||||
static void reschedule_t203(struct pri *pri);
|
||||
@@ -67,8 +67,6 @@ 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");
|
||||
@@ -94,7 +92,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(pri, h);
|
||||
Q921_INIT(h);
|
||||
h.u.m3 = 3; /* M3 = 3 */
|
||||
h.u.m2 = 0; /* M2 = 0 */
|
||||
h.u.p_f = pfbit; /* Final bit on */
|
||||
@@ -126,7 +124,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(pri, h);
|
||||
Q921_INIT(h);
|
||||
h.u.m3 = 3; /* M3 = 3 */
|
||||
h.u.m2 = 3; /* M2 = 3 */
|
||||
h.u.p_f = 1; /* Poll bit set */
|
||||
@@ -183,7 +181,6 @@ 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;
|
||||
}
|
||||
@@ -221,7 +218,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 for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a, pri->v_s);
|
||||
pri_error("ACK received outside of window, restarting\n");
|
||||
ev = q921_dchannel_down(pri);
|
||||
q921_start(pri, 1);
|
||||
pri->schedev = 1;
|
||||
@@ -263,7 +260,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(pri, h);
|
||||
Q921_INIT(h);
|
||||
h.s.x0 = 0; /* Always 0 */
|
||||
h.s.ss = 2; /* Reject */
|
||||
h.s.ft = 1; /* Frametype (01) */
|
||||
@@ -288,7 +285,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(pri, h);
|
||||
Q921_INIT(h);
|
||||
h.s.x0 = 0; /* Always 0 */
|
||||
h.s.ss = 0; /* Receive Ready */
|
||||
h.s.ft = 1; /* Frametype (01) */
|
||||
@@ -355,26 +352,9 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,9 +363,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) {
|
||||
memset(f,0,sizeof(q921_frame) + len + 2);
|
||||
Q921_INIT(pri, f->h);
|
||||
Q921_INIT(f->h);
|
||||
switch(pri->localtype) {
|
||||
case PRI_NETWORK:
|
||||
if (cr)
|
||||
@@ -456,13 +436,12 @@ 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);
|
||||
/* 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);
|
||||
/* Restart ourselves */
|
||||
pri->t203_timer = pri_schedule_event(pri, T_203, t203_expire, pri);
|
||||
} else {
|
||||
if (pri->debug & PRI_DEBUG_Q921_STATE)
|
||||
pri_message("T203 counter expired in weird state %d\n", pri->q921_state);
|
||||
pri_message("T203 counter expired in weird statd %d\n", pri->q921_state);
|
||||
pri->t203_timer = 0;
|
||||
}
|
||||
}
|
||||
@@ -698,11 +677,28 @@ void q921_reset(struct pri *pri)
|
||||
q921_discard_retransmissions(pri);
|
||||
}
|
||||
|
||||
static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
|
||||
static pri_event *__q921_receive(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:
|
||||
@@ -894,43 +890,11 @@ static pri_event *__q921_receive_qualified(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
|
||||
|
||||
@@ -42,11 +42,7 @@
|
||||
#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>
|
||||
|
||||
Reference in New Issue
Block a user