⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sl.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
		sl->statem.lsc_state = SL_STATE_OUT_OF_SERVICE;	}	return (QR_DONE);}STATIC INLINE voidsl_txc_send_sib(queue_t *q, struct sl *sl){	sl->statem.tx.sio = LSSU_SIB;	sl->statem.lssu_available = 1;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_sipo(queue_t *q, struct sl *sl){	sl_timer_stop(sl, t7);	if (sl->option.pvar == SS7_PVAR_ANSI_92)		sl_timer_stop(sl, t6);	sl->statem.tx.sio = LSSU_SIPO;	sl->statem.lssu_available = 1;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_sio(queue_t *q, struct sl *sl){	sl->statem.tx.sio = LSSU_SIO;	sl->statem.lssu_available = 1;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_sin(queue_t *q, struct sl *sl){	sl->statem.tx.sio = LSSU_SIN;	sl->statem.lssu_available = 1;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_sie(queue_t *q, struct sl *sl){	sl->statem.tx.sio = LSSU_SIE;	sl->statem.lssu_available = 1;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_msu(queue_t *q, struct sl *sl){	if (sl->rtb.q_count)		sl_timer_start(sl, t7);	sl->statem.msu_inhibited = 0;	sl->statem.lssu_available = 0;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_send_fisu(queue_t *q, struct sl *sl){	sl_timer_stop(sl, t7);	if (sl->option.pvar == SS7_PVAR_ANSI_92 && !(sl->option.popt & SS7_POPT_PCR))		sl_timer_stop(sl, t6);	sl->statem.msu_inhibited = 1;	sl->statem.lssu_available = 0;	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE voidsl_txc_fsnx_value(queue_t *q, struct sl *sl){	if (sl->statem.tx.X.fsn != sl->statem.rx.X.fsn) {		sl->statem.tx.X.fsn = sl->statem.rx.X.fsn;		sl_daedt_transmitter_wakeup(q, sl);	}}STATIC INLINE voidsl_txc_nack_to_be_sent(queue_t *q, struct sl *sl){	int pcr = sl->option.popt & SS7_POPT_PCR;	(void) pcr;	assure(!pcr);	sl->statem.tx.N.bib = sl->statem.tx.N.bib ? 0 : sl->statem.ib_mask;	ptrace(("%s: %p: [%x/%x] %d\n", MOD_NAME, sl, sl->statem.tx.N.bib | sl->statem.tx.N.bsn,		sl->statem.tx.N.fib | sl->statem.tx.N.fsn, pcr));	sl_daedt_transmitter_wakeup(q, sl);}STATIC INLINE intsl_lsc_rtb_cleared(queue_t *q, struct sl *sl){	int err;	if (sl->statem.lsc_state == SL_STATE_PROCESSOR_OUTAGE) {		sl->statem.remote_processor_outage = 0;		if (sl->statem.local_processor_outage)			return (QR_DONE);		if ((err = sl_remote_processor_recovered_ind(q, sl)))			return (err);		if ((err = sl_rtb_cleared_ind(q, sl)))			return (err);		sl_txc_send_msu(q, sl);		sl->statem.lsc_state = SL_STATE_IN_SERVICE;	}	return (QR_DONE);}STATIC int sl_check_congestion(queue_t *q, struct sl *sl);STATIC INLINE intsl_txc_bsnr_and_bibr(queue_t *q, struct sl *sl){	int err;	int pcr = sl->option.popt & SS7_POPT_PCR;	sl->statem.tx.R.bsn = sl->statem.rx.R.bsn;	sl->statem.tx.R.bib = sl->statem.rx.R.bib;	printd(("%s: %p: [%x/%x] %d\n", MOD_NAME, sl, sl->statem.tx.N.bib | sl->statem.tx.N.bsn,		sl->statem.tx.N.fib | sl->statem.tx.N.fsn, pcr));	if (sl->statem.clear_rtb) {		bufq_purge(&sl->rtb);		sl->statem.Ct = 0;		if ((err = sl_check_congestion(q, sl)))			return (err);		sl->statem.tx.F.fsn = (sl->statem.tx.R.bsn + 1) & sl->statem.sn_mask;		sl->statem.tx.L.fsn = sl->statem.tx.R.bsn;		sl->statem.tx.N.fsn = sl->statem.tx.R.bsn;		trace();		sl->statem.tx.N.fib = sl->statem.tx.R.bib;	/* for PCR too? */		sl->statem.Z = (sl->statem.tx.R.bsn + 1) & sl->statem.sn_mask;		sl->statem.z_ptr = NULL;		/* 		   FIXME: handle error return */		if ((err = sl_lsc_rtb_cleared(q, sl)))			return (err);		sl->statem.clear_rtb = 0;		sl->statem.rtb_full = 0;		return (QR_DONE);	}	printd(("%s: %p: F.fsn = %x, R.bsn = %x, mask = %x\n", MOD_NAME, sl, sl->statem.tx.F.fsn,		sl->statem.tx.R.bsn, sl->statem.sn_mask));	if (sl->statem.tx.F.fsn != ((sl->statem.tx.R.bsn + 1) & sl->statem.sn_mask)) {		if (sl->statem.sib_received) {			sl->statem.sib_received = 0;			sl_timer_stop(sl, t6);		}		do {			freemsg(bufq_dequeue(&sl->rtb));			sl->statem.Ct--;			sl->statem.tx.F.fsn = (sl->statem.tx.F.fsn + 1) & sl->statem.sn_mask;		} while (sl->statem.tx.F.fsn != ((sl->statem.tx.R.bsn + 1) & sl->statem.sn_mask));		if ((err = sl_check_congestion(q, sl)))			return (err);		sl_daedt_transmitter_wakeup(q, sl);		if (sl->rtb.q_count == 0) {			sl_timer_stop(sl, t7);		} else {			sl_timer_start(sl, t7);		}		if (!pcr || (sl->rtb.q_msgs < sl->config.N1 && sl->rtb.q_count < sl->config.N2)) {			sl->statem.rtb_full = 0;		}		if (SN_OUTSIDE(sl->statem.tx.F.fsn, sl->statem.Z, sl->statem.tx.L.fsn)		    || !sl->rtb.q_count) {			sl->statem.Z = sl->statem.tx.F.fsn;			sl->statem.z_ptr = sl->rtb.q_head;		}	}	if (!pcr && sl->statem.tx.N.fib != sl->statem.tx.R.bib) {		if (sl->statem.sib_received) {			sl->statem.sib_received = 0;			sl_timer_stop(sl, t6);		}		sl->statem.tx.N.fib = sl->statem.tx.R.bib;		sl->statem.tx.N.fsn = (sl->statem.tx.F.fsn - 1) & sl->statem.sn_mask;		if ((sl->statem.z_ptr = sl->rtb.q_head) != NULL) {			sl->statem.retrans_cycle = 1;		}		sl_daedt_transmitter_wakeup(q, sl);	}	return (QR_DONE);}STATIC INLINE voidsl_txc_sib_received(queue_t *q, struct sl *sl){	/* 	   FIXME: consider these variations for all */	if (sl->option.pvar == SS7_PVAR_ANSI_92 && sl->statem.lssu_available)		if (sl->statem.tx.sio != LSSU_SIB)			return;	if (sl->option.pvar != SS7_PVAR_ITUT_93 && !sl->rtb.q_count)		return;	if (!sl->statem.sib_received) {		sl_timer_start(sl, t6);		sl->statem.sib_received = 1;	}	sl_timer_start(sl, t7);}STATIC INLINE intsl_txc_clear_rtb(queue_t *q, struct sl *sl){	bufq_purge(&sl->rtb);	sl->statem.Ct = 0;	sl->statem.clear_rtb = 1;	sl->statem.rtb_full = 0;	/* added */	/* 	 * FIXME: should probably follow more of the ITUT flush_buffers stuff	 * like reseting Z and FSNF, FSNL, FSNT.	 */	return sl_check_congestion(q, sl);}STATIC INLINE intsl_txc_clear_tb(queue_t *q, struct sl *sl){	bufq_purge(&sl->tb);	flushq(sl->iq, FLUSHDATA);	sl->statem.Cm = 0;	return sl_check_congestion(q, sl);}STATIC INLINE voidsl_txc_flush_buffers(queue_t *q, struct sl *sl){	bufq_purge(&sl->rtb);	sl->statem.rtb_full = 0;	sl->statem.Ct = 0;	bufq_purge(&sl->tb);	flushq(sl->iq, FLUSHDATA);	sl->statem.Cm = 0;	sl->statem.Z = 0;	sl->statem.z_ptr = NULL;	/* 	   Z =0 error in ITUT 93 and ANSI */	sl->statem.Z = sl->statem.tx.F.fsn = (sl->statem.tx.R.bsn + 1) & sl->statem.sn_mask;	sl->statem.tx.L.fsn = sl->statem.rx.R.bsn;	sl->statem.rx.T.fsn = sl->statem.rx.R.bsn;	sl_timer_stop(sl, t7);}STATIC INLINE voidsl_rc_fsnt_value(queue_t *q, struct sl *sl){	sl->statem.rx.T.fsn = sl->statem.tx.N.fsn;}STATIC INLINE intsl_txc_retrieval_request_and_fsnc(queue_t *q, struct sl *sl, sl_ulong fsnc){	mblk_t *mp;	int err;	sl->statem.tx.C.fsn = fsnc & (sl->statem.sn_mask);	/* 	 *  FIXME: Q.704/5.7.2 states:	 *	 *  5.7.2   If a changeover order or acknowledgement containing an	 *  unreasonable value of the forward sequence number is received, no	 *  buffer updating or retrieval is performed, and new traffic is	 *  started on the alternative signalling link(s).	 *	 *  It will be necessary to check FSNC for "reasonableness" here and	 *  flush RTB and TB and return retrieval-complete indication with a	 *  return code of "unreasonable FSNC".	 *	 *  (Tell the SIGTRAN working group and M2UA guys about this!)	 */	while (sl->rtb.q_count && sl->statem.tx.F.fsn != ((fsnc + 1) & sl->statem.sn_mask)) {		freemsg(bufq_dequeue(&sl->rtb));		sl->statem.Ct--;		sl->statem.tx.F.fsn = (sl->statem.tx.F.fsn + 1) & sl->statem.sn_mask;	}	while ((mp = bufq_dequeue(&sl->tb))) {		sl->statem.Cm--;		bufq_queue(&sl->rtb, mp);		sl->statem.Ct++;		if (!sl->statem.Cm)			qenable(sl->iq);	/* back enable */	}	sl->statem.Z = sl->statem.tx.F.fsn = (sl->statem.tx.C.fsn + 1) & sl->statem.sn_mask;	while ((mp = bufq_dequeue(&sl->rtb))) {		sl->statem.Ct--;		if ((err = sl_retrieved_message_ind(q, sl, mp)))			return (err);	}	sl->statem.rtb_full = 0;	if ((err = sl_retrieval_complete_ind(q, sl)))		return (err);	sl->statem.Cm = 0;	sl->statem.Ct = 0;	sl->statem.tx.N.fsn = sl->statem.tx.L.fsn = sl->statem.tx.C.fsn;	return (QR_DONE);}STATIC INLINE voidsl_daedt_fisu(queue_t *q, struct sl *sl, mblk_t *mp){	if (sl->option.popt & SS7_POPT_XSN) {		*(sl_ushort *) mp->b_wptr = htons(sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		mp->b_wptr += sizeof(sl_ushort);		*(sl_ushort *) mp->b_wptr = htons(sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		mp->b_wptr += sizeof(sl_ushort);		*(sl_ushort *) mp->b_wptr = 0;		mp->b_wptr += sizeof(sl_ushort);	} else {		*(sl_uchar *) mp->b_wptr = (sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		mp->b_wptr += sizeof(sl_uchar);		*(sl_uchar *) mp->b_wptr = (sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		mp->b_wptr += sizeof(sl_uchar);		*(sl_uchar *) mp->b_wptr = 0;		mp->b_wptr += sizeof(sl_uchar);	}	sl->statem.txc_state = SL_STATE_SLEEPING;	printd(("%s: %p: FISU [%x/%x] %ld ->\n", MOD_NAME, sl,		sl->statem.tx.N.bib | sl->statem.tx.N.bsn,		sl->statem.tx.N.fib | sl->statem.tx.N.fsn, sl->option.popt & SS7_POPT_PCR));}STATIC INLINE voidsl_daedt_lssu(queue_t *q, struct sl *sl, mblk_t *mp){	if (sl->option.popt & SS7_POPT_XSN) {		*(sl_ushort *) mp->b_wptr = htons(sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		mp->b_wptr += sizeof(sl_ushort);		*(sl_ushort *) mp->b_wptr = htons(sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		mp->b_wptr += sizeof(sl_ushort);		*(sl_ushort *) mp->b_wptr = htons(1);		mp->b_wptr += sizeof(sl_ushort);	} else {		*(sl_uchar *) mp->b_wptr = (sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		mp->b_wptr += sizeof(sl_uchar);		*(sl_uchar *) mp->b_wptr = (sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		mp->b_wptr += sizeof(sl_uchar);		*(sl_uchar *) mp->b_wptr = 1;		mp->b_wptr += sizeof(sl_uchar);	}	*(sl_uchar *) mp->b_wptr = (sl->statem.tx.sio);	mp->b_wptr += sizeof(sl_uchar);	if (sl->statem.tx.sio != LSSU_SIB)		sl->statem.txc_state = SL_STATE_SLEEPING;	switch (sl->statem.tx.sio) {	case LSSU_SIO:		printd(("%s: %p: SIO ->\n", MOD_NAME, sl));		break;	case LSSU_SIN:		printd(("%s: %p: SIN ->\n", MOD_NAME, sl));		break;	case LSSU_SIE:		printd(("%s: %p: SIE ->\n", MOD_NAME, sl));		break;	case LSSU_SIOS:		printd(("%s: %p: SIOS ->\n", MOD_NAME, sl));		break;	case LSSU_SIPO:		printd(("%s: %p: SIPO ->\n", MOD_NAME, sl));		break;	case LSSU_SIB:		printd(("%s: %p: SIB ->\n", MOD_NAME, sl));		break;	}}STATIC INLINE voidsl_daedt_msu(queue_t *q, struct sl *sl, mblk_t *mp){	int len = msgdsize(mp);	if (sl->option.popt & SS7_POPT_XSN) {		((sl_ushort *) mp->b_rptr)[0] = htons(sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		((sl_ushort *) mp->b_rptr)[1] = htons(sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		((sl_ushort *) mp->b_rptr)[2] = htons(len - 6 < 512 ? len - 6 : 511);	} else {		((sl_uchar *) mp->b_rptr)[0] = (sl->statem.tx.N.bsn | sl->statem.tx.N.bib);		((sl_uchar *) mp->b_rptr)[1] = (sl->statem.tx.N.fsn | sl->statem.tx.N.fib);		((sl_uchar *) mp->b_rptr)[2] = (len - 3 < 64 ? len - 3 : 63);	}	printd(("%s: %p: MSU [%d] ->\n", MOD_NAME, sl, len));}STATIC INLINE mblk_t *sl_txc_transmission_request(queue_t *q, struct sl *sl){	mblk_t *mp = NULL;	int pcr;	if (sl->statem.txc_state != SL_STATE_IN_SERVICE)		return (mp);	pcr = sl->option.popt & SS7_POPT_PCR;	if (sl->statem.lssu_available) {		if ((mp = allocb(7, BPRI_HI))) {			if (sl->statem.tx.sio == LSSU_SIB)				sl->statem.lssu_available = 0;			sl->statem.tx.N.fsn = sl->statem.tx.L.fsn;			// sl->statem.tx.N.bib = sl->statem.tx.N.bib;			sl->statem.tx.N.bsn = (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;			// sl->statem.tx.N.fib = sl->statem.tx.N.fib;			sl_daedt_lssu(q, sl, mp);		}		return (mp);	}	if (sl->statem.msu_inhibited) {		if ((mp = allocb(6, BPRI_HI))) {			sl->statem.tx.N.fsn = sl->statem.tx.L.fsn;			// sl->statem.tx.N.bib = sl->statem.tx.N.bib;			sl->statem.tx.N.bsn = (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;			// sl->statem.tx.N.fib = sl->statem.tx.N.fib;			sl_daedt_fisu(q, sl, mp);		}		return (mp);	}	if (pcr) {		if ((sl->rtb.q_msgs < sl->config.N1)		    && (sl->rtb.q_count < sl->config.N2)) {			sl->statem.forced_retransmission = 0;			sl->statem.rtb_full = 0;		}		if (sl->tb.q_count && sl->statem.rtb_full) {			sl->statem.forced_retransmission = 1;		}	}	if ((!pcr && sl->statem.retrans_cycle)	    || (pcr && (sl->statem.forced_retransmission || (!sl->tb.q_count && sl->rtb.q_count)))) {		mblk_t *bp = sl->statem.z_ptr;		if (bp && !(mp = dupmsg(bp)))			return (mp);		if (!bp && pcr) {			bp = sl->rtb.q_head;			if (bp && !(mp = dupmsg(bp)))				return (mp);			sl->statem.z_ptr = bp;			sl->statem.Z = sl->statem.tx.F.fsn;		}		if (mp) {			sl->statem.z_ptr = bp->b_next;			if (pcr) {				sl->statem.tx.N.fsn = sl->statem.Z;				// sl->statem.tx.N.fib = sl->statem.tx.N.fib;				sl->statem.tx.N.bsn =				    (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;				// sl->statem.tx.N.bib = sl->statem.tx.N.bib;				sl->statem.Z = (sl->statem.Z + 1) & sl->statem.sn_mask;			} else {				sl->statem.tx.N.fsn =				    (sl->statem.tx.N.fsn + 1) & sl->statem.sn_mask;				// sl->statem.tx.N.fib = sl->statem.tx.N.fib;				sl->statem.tx.N.bsn =				    (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;				// sl->statem.tx.N.bib = sl->statem.tx.N.bib;			}			sl_daedt_msu(q, sl, mp);			if (sl->statem.tx.N.fsn == sl->statem.tx.L.fsn || sl->statem.z_ptr == NULL)				sl->statem.retrans_cycle = 0;			return (mp);		}	}	if ((!pcr && (!sl->tb.q_count || sl->statem.rtb_full))	    || (pcr && (!sl->tb.q_count && !sl->rtb.q_count))) {		if ((mp = allocb(6, BPRI_HI))) {			sl->statem.tx.N.fsn = sl->statem.tx.L.fsn;			// sl->statem.tx.N.bib = sl->statem.tx.N.bib;			sl->statem.tx.N.bsn = (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;			// sl->statem.tx.N.fib = sl->statem.tx.N.fib;			sl_daedt_fisu(q, sl, mp);		}		return (mp);	} else {		spin_lock(&sl->tb.q_lock);		if ((mp = bufq_head(&sl->tb)) && (mp = dupmsg(mp))) {			mblk_t *bp = bufq_dequeue(&sl->tb);			sl->statem.Cm--;			if (!sl->statem.Cm)				qenable(sl->iq);	/* back enable */			sl->statem.tx.L.fsn = (sl->statem.tx.L.fsn + 1) & sl->statem.sn_mask;			sl->statem.tx.N.fsn = sl->statem.tx.L.fsn;			if (!sl->rtb.q_count)				sl_timer_start(sl, t7);			bufq_queue(&sl->rtb, bp);			sl->statem.Ct++;			sl_rc_fsnt_value(q, sl);			if (pcr) {				if ((sl->rtb.q_msgs >= sl->config.N1)				    || (sl->rtb.q_count >= sl->config.N2)) {					sl->statem.rtb_full = 1;					sl->statem.forced_retransmission = 1;				}			} else {				if ((sl->rtb.q_msgs >= sl->config.N1)				    || (sl->rtb.q_count >= sl->config.N2)				    || (sl->statem.tx.L.fsn ==					((sl->statem.tx.F.fsn - 2) & sl->statem.sn_mask)))					sl->statem.rtb_full = 1;			}			// sl->statem.tx.N.bib = sl->statem.tx.N.bib;			sl->statem.tx.N.bsn = (sl->statem.tx.X.fsn - 1) & sl->statem.sn_mask;			// sl->statem.tx.N.fib = sl->statem.tx.N.fib;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -