Merge of Q.921 rewrite branch for wider testing.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1406 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
14f04072c8
commit
4d3bb14731
2
Makefile
2
Makefile
@ -144,7 +144,7 @@ install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
|
||||
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
|
||||
#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)
|
||||
install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(libdir)
|
||||
if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(libdir); fi
|
||||
|
29
pri.c
29
pri.c
@ -144,7 +144,12 @@ static void pri_default_timers(struct pri *ctrl, int switchtype)
|
||||
/* Set timer values to standard defaults. Time is in ms. */
|
||||
ctrl->timers[PRI_TIMER_N200] = 3; /* Max numer of Q.921 retransmissions */
|
||||
ctrl->timers[PRI_TIMER_N202] = 3; /* Max numer of transmissions of the TEI identity request message */
|
||||
ctrl->timers[PRI_TIMER_K] = 7; /* Max number of outstanding I-frames */
|
||||
|
||||
if (ctrl->bri == 1)
|
||||
ctrl->timers[PRI_TIMER_K] = 1; /* Max number of outstanding I-frames */
|
||||
else
|
||||
ctrl->timers[PRI_TIMER_K] = 7; /* Max number of outstanding I-frames */
|
||||
|
||||
ctrl->timers[PRI_TIMER_T200] = 1000; /* Time between SABME's */
|
||||
ctrl->timers[PRI_TIMER_T202] = 10 * 1000; /* Min time between transmission of TEI Identity request messages */
|
||||
ctrl->timers[PRI_TIMER_T203] = 10 * 1000; /* Max time without exchanging packets */
|
||||
@ -154,6 +159,7 @@ static void pri_default_timers(struct pri *ctrl, int switchtype)
|
||||
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 */
|
||||
ctrl->timers[PRI_TIMER_T303] = 4 * 1000; /* Length between SETUP retransmissions and timeout */
|
||||
ctrl->timers[PRI_TIMER_T309] = 6000; /* Time to wait before clearing calls in case of D-channel transient event. Q.931 specifies 6-90 seconds */
|
||||
|
||||
ctrl->timers[PRI_TIMER_T_HOLD] = 4 * 1000; /* Wait for HOLD request response. */
|
||||
ctrl->timers[PRI_TIMER_T_RETRIEVE] = 4 * 1000;/* Wait for RETRIEVE request response. */
|
||||
@ -343,9 +349,16 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Start Q.921 layer, Wait if we're the network */
|
||||
if (p)
|
||||
q921_start(p, p->localtype == PRI_CPE);
|
||||
p->k = p->timers[PRI_TIMER_K];
|
||||
|
||||
if (p->tei == Q921_TEI_GROUP && p->sapi == Q921_SAPI_LAYER2_MANAGEMENT && p->localtype == PRI_CPE) {
|
||||
p->subchannel = __pri_new_tei(-1, p->localtype, p->switchtype, p, NULL, NULL, NULL, Q921_TEI_PRI, 1);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
q921_start(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
@ -363,11 +376,15 @@ void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars)
|
||||
|
||||
int pri_restart(struct pri *pri)
|
||||
{
|
||||
#if 0
|
||||
/* Restart Q.921 layer */
|
||||
if (pri) {
|
||||
q921_reset(pri, 1);
|
||||
q921_start(pri, pri->localtype == PRI_CPE);
|
||||
}
|
||||
#else
|
||||
pri_error(pri, "pri_restart should never be called !!!!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1303,12 +1320,14 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
}
|
||||
used = pri_snprintf(buf, used, buf_size, "Q921 Outstanding: %u\n", q921outstanding);
|
||||
#endif
|
||||
used = pri_snprintf(buf, used, buf_size, "Window Length: %d/%d\n", ctrl->windowlen,
|
||||
#if 0
|
||||
used = pri_snprintf(buf, used, buf_size, "Window Length: %d/%d\n", ctrl->k,
|
||||
ctrl->window);
|
||||
used = pri_snprintf(buf, used, buf_size, "Sentrej: %d\n", ctrl->sentrej);
|
||||
used = pri_snprintf(buf, used, buf_size, "SolicitFbit: %d\n", ctrl->solicitfbit);
|
||||
used = pri_snprintf(buf, used, buf_size, "Retrans: %d\n", ctrl->retrans);
|
||||
used = pri_snprintf(buf, used, buf_size, "Busy: %d\n", ctrl->busy);
|
||||
#endif
|
||||
used = pri_snprintf(buf, used, buf_size, "Overlap Dial: %d\n", ctrl->overlapdial);
|
||||
used = pri_snprintf(buf, used, buf_size, "Logical Channel Mapping: %d\n",
|
||||
ctrl->chan_mapping_logical);
|
||||
|
@ -89,25 +89,30 @@ struct pri {
|
||||
unsigned int hold_support:1;/* TRUE if upper layer supports call hold. */
|
||||
unsigned int deflection_support:1;/* TRUE if upper layer supports call deflection/rerouting. */
|
||||
|
||||
/* MDL variables */
|
||||
int mdl_error;
|
||||
int mdl_error_state;
|
||||
int mdl_timer;
|
||||
int mdl_free_me;
|
||||
|
||||
/* Q.921 State */
|
||||
int q921_state;
|
||||
int window; /* Max window size */
|
||||
int windowlen; /* Fullness of window */
|
||||
int k;
|
||||
int RC;
|
||||
int peer_rx_busy:1;
|
||||
int own_rx_busy:1;
|
||||
int acknowledge_pending:1;
|
||||
int reject_exception:1;
|
||||
|
||||
int v_s; /* Next N(S) for transmission */
|
||||
int v_a; /* Last acknowledged frame */
|
||||
int v_r; /* Next frame expected to be received */
|
||||
int v_na; /* What we've told our peer we've acknowledged */
|
||||
int solicitfbit; /* Have we sent an I or S frame with the F-bit set? */
|
||||
int retrans; /* Retransmissions */
|
||||
int sentrej; /* Are we in reject state */
|
||||
|
||||
int cref; /* Next call reference value */
|
||||
|
||||
int busy; /* Peer is busy */
|
||||
int l3initiated;
|
||||
|
||||
/* Various timers */
|
||||
int sabme_timer; /* SABME retransmit */
|
||||
int sabme_count; /* SABME retransmit counter for BRI */
|
||||
int t203_timer; /* Max idle time */
|
||||
int t202_timer;
|
||||
int n202_counter;
|
||||
@ -515,6 +520,8 @@ struct q931_call {
|
||||
-1 - No reverse charging
|
||||
1 - Reverse charging
|
||||
0,2-7 - Reserved for future use */
|
||||
/*! \brief TEI associated with call */
|
||||
int tei;
|
||||
int t303_timer;
|
||||
int t303_expirycnt;
|
||||
|
||||
@ -627,13 +634,40 @@ static inline int BRI_TE_PTMP(struct pri *mypri)
|
||||
return pri->bri && (((pri)->localtype == PRI_CPE) && ((pri)->tei == Q921_TEI_GROUP));
|
||||
}
|
||||
|
||||
static inline int PRI_PTP(struct pri *mypri)
|
||||
static inline int NT_MODE(struct pri *mypri)
|
||||
{
|
||||
struct pri *pri;
|
||||
|
||||
pri = PRI_MASTER(mypri);
|
||||
|
||||
return !pri->bri;
|
||||
return pri->localtype == PRI_NETWORK;
|
||||
}
|
||||
|
||||
static inline int TE_MODE(struct pri *mypri)
|
||||
{
|
||||
struct pri *pri;
|
||||
|
||||
pri = PRI_MASTER(mypri);
|
||||
|
||||
return pri->localtype == PRI_CPE;
|
||||
}
|
||||
|
||||
static inline int PTP_MODE(struct pri *mypri)
|
||||
{
|
||||
struct pri *pri;
|
||||
|
||||
pri = PRI_MASTER(mypri);
|
||||
|
||||
return pri->tei == Q921_TEI_PRI;
|
||||
}
|
||||
|
||||
static inline int PTMP_MODE(struct pri *mypri)
|
||||
{
|
||||
struct pri *pri;
|
||||
|
||||
pri = PRI_MASTER(mypri);
|
||||
|
||||
return pri->tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
#define Q931_DUMMY_CALL_REFERENCE -1
|
||||
|
33
pri_q921.h
33
pri_q921.h
@ -166,36 +166,41 @@ typedef struct q921_frame {
|
||||
} q921_frame;
|
||||
|
||||
#define Q921_INC(j) (j) = (((j) + 1) % 128)
|
||||
#define Q921_DEC(j) (j) = (((j) - 1) % 128)
|
||||
|
||||
typedef enum q921_state {
|
||||
Q921_DOWN = 0,
|
||||
Q921_TEI_UNASSIGNED,
|
||||
Q921_TEI_AWAITING_ESTABLISH,
|
||||
Q921_TEI_AWAITING_ASSIGN,
|
||||
Q921_TEI_ASSIGNED,
|
||||
Q921_NEGOTIATION,
|
||||
Q921_LINK_CONNECTION_RELEASED, /* Also known as TEI_ASSIGNED */
|
||||
Q921_LINK_CONNECTION_ESTABLISHED,
|
||||
Q921_AWAITING_ESTABLISH,
|
||||
Q921_AWAITING_RELEASE
|
||||
/* All states except Q921_DOWN are defined in Q.921 SDL diagrams */
|
||||
Q921_TEI_UNASSIGNED = 1,
|
||||
Q921_ASSIGN_AWAITING_TEI = 2,
|
||||
Q921_ESTABLISH_AWAITING_TEI = 3,
|
||||
Q921_TEI_ASSIGNED = 4,
|
||||
Q921_AWAITING_ESTABLISHMENT = 5,
|
||||
Q921_AWAITING_RELEASE = 6,
|
||||
Q921_MULTI_FRAME_ESTABLISHED = 7,
|
||||
Q921_TIMER_RECOVERY = 8,
|
||||
} q921_state;
|
||||
|
||||
static inline int Q921_ADD(int a, int b)
|
||||
{
|
||||
return (a + b) % 128;
|
||||
}
|
||||
|
||||
/* Dumps a *known good* Q.921 packet */
|
||||
extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
|
||||
|
||||
/* Bring up the D-channel */
|
||||
extern void q921_start(struct pri *pri, int now);
|
||||
extern void q921_start(struct pri *pri);
|
||||
|
||||
extern void q921_reset(struct pri *pri, int reset_iqueue);
|
||||
//extern void q921_reset(struct pri *pri, int reset_iqueue);
|
||||
|
||||
extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
|
||||
|
||||
extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr);
|
||||
extern int q921_transmit_iframe(struct pri *pri, int tei, void *buf, int len, int cr);
|
||||
|
||||
extern int q921_transmit_uiframe(struct pri *pri, void *buf, int len);
|
||||
|
||||
extern pri_event *q921_dchannel_up(struct pri *pri);
|
||||
|
||||
extern pri_event *q921_dchannel_down(struct pri *pri);
|
||||
//extern pri_event *q921_dchannel_down(struct pri *pri);
|
||||
|
||||
#endif
|
||||
|
@ -452,7 +452,7 @@ extern int maintenance_service_ack(struct pri *pri, q931_call *call);
|
||||
/* Q.SIG specific */
|
||||
#define QSIG_IE_TRANSIT_COUNT 0x31
|
||||
|
||||
extern int q931_receive(struct pri *pri, q931_h *h, int len);
|
||||
extern int q931_receive(struct pri *pri, int tei, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
|
26
q931.c
26
q931.c
@ -3926,12 +3926,12 @@ static void init_header(struct pri *ctrl, q931_call *call, unsigned char *buf, q
|
||||
*mhb = mh;
|
||||
}
|
||||
|
||||
static int q931_xmit(struct pri *ctrl, q931_h *h, int len, int cr, int uiframe)
|
||||
static int q931_xmit(struct pri *ctrl, int tei, q931_h *h, int len, int cr, int uiframe)
|
||||
{
|
||||
if (uiframe) {
|
||||
q921_transmit_uiframe(ctrl, h, len);
|
||||
} else {
|
||||
q921_transmit_iframe(ctrl, h, len, cr);
|
||||
q921_transmit_iframe(ctrl, tei, h, len, cr);
|
||||
}
|
||||
/* The transmit operation might dump the q921 header, so logging the q931
|
||||
message body after the transmit puts the sections of the message in the
|
||||
@ -3998,14 +3998,6 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
len = sizeof(buf) - len;
|
||||
|
||||
ctrl = call->pri;
|
||||
if (BRI_TE_PTMP(ctrl)) {
|
||||
/*
|
||||
* Must use the BRI subchannel structure to send with the correct TEI.
|
||||
* Note: If the subchannel is NULL then there is no TEI assigned and
|
||||
* we should not be sending anything out at this time.
|
||||
*/
|
||||
ctrl = ctrl->subchannel;
|
||||
}
|
||||
if (ctrl) {
|
||||
int uiframe;
|
||||
|
||||
@ -4054,7 +4046,7 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
ctrl, ctrl->tei, ctrl->sapi,
|
||||
call->pri, call->pri->tei, call->pri->sapi);
|
||||
}
|
||||
q931_xmit(ctrl, h, len, 1, uiframe);
|
||||
q931_xmit(ctrl, ctrl->tei, h, len, 1, uiframe);
|
||||
}
|
||||
call->acked = 1;
|
||||
return 0;
|
||||
@ -5776,7 +5768,7 @@ static struct q931_call *q931_get_subcall(struct pri *ctrl, struct q931_call *ma
|
||||
return cur;
|
||||
}
|
||||
|
||||
int q931_receive(struct pri *ctrl, q931_h *h, int len)
|
||||
int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len)
|
||||
{
|
||||
q931_mh *mh;
|
||||
q931_call *c;
|
||||
@ -5810,7 +5802,7 @@ int q931_receive(struct pri *ctrl, q931_h *h, int len)
|
||||
KLUDGE this by changing byte 4 from a 0xf (SERVICE)
|
||||
to a 0x7 (SERVICE ACKNOWLEDGE) */
|
||||
h->raw[h->crlen + 2] -= 0x8;
|
||||
q931_xmit(ctrl, h, len, 1, 0);
|
||||
q931_xmit(ctrl, ctrl->tei, h, len, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5973,11 +5965,11 @@ static int post_handle_maintenance_message(struct pri *ctrl, int protodisc, stru
|
||||
switch (0x0f & c->changestatus) {
|
||||
case SERVICE_CHANGE_STATUS_INSERVICE:
|
||||
ctrl->ev.e = PRI_EVENT_DCHAN_UP;
|
||||
q921_dchannel_up(ctrl);
|
||||
//q921_dchannel_up(ctrl);
|
||||
break;
|
||||
case SERVICE_CHANGE_STATUS_OUTOFSERVICE:
|
||||
ctrl->ev.e = PRI_EVENT_DCHAN_DOWN;
|
||||
q921_dchannel_down(ctrl);
|
||||
//q921_dchannel_down(ctrl);
|
||||
break;
|
||||
default:
|
||||
pri_error(ctrl, "!! Don't know how to handle span service change status '%d'\n", (0x0f & c->changestatus));
|
||||
@ -5997,11 +5989,11 @@ static int post_handle_maintenance_message(struct pri *ctrl, int protodisc, stru
|
||||
switch (0x0f & c->changestatus) {
|
||||
case SERVICE_CHANGE_STATUS_INSERVICE:
|
||||
ctrl->ev.e = PRI_EVENT_DCHAN_UP;
|
||||
q921_dchannel_up(ctrl);
|
||||
//q921_dchannel_up(ctrl);
|
||||
break;
|
||||
case SERVICE_CHANGE_STATUS_OUTOFSERVICE:
|
||||
ctrl->ev.e = PRI_EVENT_DCHAN_DOWN;
|
||||
q921_dchannel_down(ctrl);
|
||||
//q921_dchannel_down(ctrl);
|
||||
break;
|
||||
default:
|
||||
pri_error(ctrl, "!! Don't know how to handle span service change status '%d'\n", (0x0f & c->changestatus));
|
||||
|
Loading…
Reference in New Issue
Block a user