📄 sl.c
字号:
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 + -