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:
Matthew Fredrickson 2010-01-13 19:37:59 +00:00
parent 14f04072c8
commit 4d3bb14731
7 changed files with 1413 additions and 657 deletions

View File

@ -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

27
pri.c
View File

@ -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 */
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);

View File

@ -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

View File

@ -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

View File

@ -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);

1836
q921.c

File diff suppressed because it is too large Load Diff

26
q931.c
View File

@ -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));