📄 sl_sm.h
字号:
sl_daedt_fisu(sl); return; } 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 *mp = sl->statem.z_ptr; if ( !mp && pcr ) { mp = sl->statem.z_ptr = sl->rtb.q_head; sl->statem.Z = sl->statem.tx.F.fsn; } if ( mp ) { sl->statem.z_ptr = mp->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(sl, mp); if ( sl->statem.tx.N.fsn == sl->statem.tx.L.fsn || sl->statem.z_ptr == NULL ) sl->statem.retrans_cycle = 0; return; } } if ( (!pcr && (!sl->tb.q_count || sl->statem.rtb_full) ) || ( pcr && (!sl->tb.q_count && !sl->rtb.q_count ) ) ) { 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(sl); return; } else { mblk_t *mp; if ( !(mp = bufq_dequeue(&sl->tb)) ) return; sl->statem.Cm--; 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(t7); bufq_queue(&sl->rtb, mp); sl->statem.Ct++; sl_rc_fsnt_value(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; */ sl_daedt_msu(sl, mp); }}static inline void sl_rc_start(sl_t *sl) { if ( sl->statem.rc_state == SL_STATE_IDLE ) { sl->statem.rx.X.fsn = 0; sl->statem.rx.X.fib = sl->statem.ib_mask; sl->statem.rx.F.fsn = 0; sl->statem.rx.T.fsn = sl->statem.sn_mask; sl->statem.rtr = 0; /* Basic only (note 1). */ if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) sl->statem.msu_fisu_accepted = 1; else sl->statem.msu_fisu_accepted = 0; sl->statem.abnormal_bsnr = 0; sl->statem.abnormal_fibr = 0; /* Basic only (note 1). */ sl->statem.congestion_discard = 0; sl->statem.congestion_accept = 0; sl->dcalls->daedr_start(sl); sl->statem.rc_state = SL_STATE_IN_SERVICE; return; /* * Note 1 - Although rtr and abnormal_fibr are only * applicable to the Basic procedure (and not PCR), these * state machine variables are never examined by PCR * routines, so PCR and basic can share the same start * procedures. */ }}static inline void sl_rc_reject_msu_fisu(sl_t *sl) { sl->statem.msu_fisu_accepted = 0;}static inline void sl_rc_accept_msu_fisu(sl_t *sl) { sl->statem.msu_fisu_accepted = 1;}static inline void sl_rc_retrieve_fsnx(sl_t *sl){ sl_txc_fsnx_value(sl); /* error in 93 spec */ sl->statem.congestion_discard = 0; sl->statem.congestion_accept = 0; sl_cc_normal(sl); sl->statem.rtr = 0; /* basic only */}static inline void sl_rc_align_fsnx(sl_t *sl) { sl_txc_fsnx_value(sl);}static inline void sl_rc_clear_rb(sl_t *sl) { flushq(sl->rq, FLUSHDATA); sl_l3_rb_cleared(sl);}static inline void sl_rc_retrieve_bsnt(sl_t *sl) { sl->statem.rx.T.bsn = (sl->statem.rx.X.fsn - 1)&0x7F; sl_l3_bsnt(sl, sl->statem.rx.T.bsn);}static void sl_t5_timeout(sl_t *sl) { if ( sl->statem.cc_state == SL_STATE_BUSY ) { sl_txc_send_sib(sl); sl_timer_start(t5); }}static inline void sl_cc_busy(sl_t *sl) { if ( sl->statem.cc_state == SL_STATE_NORMAL) { sl_txc_send_sib(sl); sl_timer_start(t5); sl->statem.cc_state = SL_STATE_BUSY; }}static inline void sl_rc_congestion_discard(sl_t *sl) { sl->statem.congestion_discard = 1; sl_cc_busy(sl);}static inline void sl_rc_congestion_accept(sl_t *sl) { sl->statem.congestion_accept = 1; sl_cc_busy(sl);}static inline void sl_rc_no_congestion(sl_t *sl) { sl->statem.congestion_discard = 0; sl->statem.congestion_accept = 0; sl_cc_normal(sl); sl_txc_fsnx_value(sl); if ( sl->statem.rtr == 1 ) /* rtr never set for PCR */ { sl_txc_nack_to_be_sent(sl); sl->statem.rx.X.fib = sl->statem.rx.X.fib ?0:sl->statem.ib_mask; }}static inline void sl_lsc_congestion_discard(sl_t *sl) { sl_rc_congestion_discard(sl); sl->statem.l3_congestion_detect = 1;}static inline void sl_lsc_congestion_accept(sl_t *sl) { sl_rc_congestion_accept(sl); sl->statem.l3_congestion_detect = 1;}static inline void sl_lsc_no_congestion(sl_t *sl) { sl_rc_no_congestion(sl); sl->statem.l3_congestion_detect = 0;}/* * -------------------------------------------------------------------------- * * These congestion functions are implementation dependent. We should define * a congestion onset level and set congestion accept at that point. We * should also define a second congestion onset level and set congestion * discard at that point. For STREAMS, the upstream congestion can be * detected in two ways: 1) canputnext(): is the upstream module flow * controlled; and, 2) canput(): are we flow controlled. If the upstream * module is flow controlled, then we can accept MSUs and place them on our * own read queue. If we are flow contolled, then we have no choice but to * discard the message. In addition, and because upstream message processing * times are likely more sensitive to the number of backlogged messages than * they are to the number of backlogged message octets, we have some * configurable thresholds of backlogging and keep track of backlogged * messages. * * -------------------------------------------------------------------------- */static inline void sl_rb_congestion_function(sl_t *sl) { if ( !sl->statem.l3_congestion_detect ) { if ( sl->statem.l2_congestion_detect ) { if ( sl->statem.Cr <= sl->config.rb_abate && canputnext(sl->rq) ) { sl_rc_no_congestion(sl); sl->statem.l2_congestion_detect = 0; } } else { if ( sl->statem.Cr >= sl->config.rb_discard || !canput(sl->rq) ) { sl_rc_congestion_discard(sl); sl->statem.l2_congestion_detect = 1; } else if ( sl->statem.Cr >= sl->config.rb_accept || !canputnext(sl->rq) ) { sl_rc_congestion_accept(sl); sl->statem.l2_congestion_detect = 1; } } }}static inline void sl_lsc_sio(sl_t *sl) { switch ( sl->statem.lsc_state) { case SL_STATE_OUT_OF_SERVICE: case SL_STATE_INITIAL_ALIGNMENT: break; default: sl_timer_stop(t1); /* ok if not running */ sl->statem.failure_reason = SL_FAIL_RECEIVED_SIO; sl_l3_out_of_service(sl, sl->statem.failure_reason); sl_rc_stop(sl); sl->dcalls->suerm_stop(sl); sl_poc_stop(sl); /* ok if ANSI */ sl_txc_send_sios(sl); sl->statem.emergency = 0; /* FIXME: reinspect */ sl->statem.local_processor_outage = 0; sl->statem.remote_processor_outage = 0; /* ok if ITUT */ sl->statem.lsc_state = SL_STATE_OUT_OF_SERVICE; break; }}static inline void sl_lsc_alignment_not_possible(sl_t *sl) { sl->statem.failure_reason = SL_FAIL_ALIGNMENT_NOT_POSSIBLE; sl_l3_out_of_service(sl, sl->statem.failure_reason); sl_rc_stop(sl); sl_txc_send_sios(sl); sl->statem.local_processor_outage = 0; sl->statem.emergency = 0; sl->statem.lsc_state = SL_STATE_OUT_OF_SERVICE;}static void sl_t3_timeout(sl_t *sl) { if ( sl->statem.iac_state == SL_STATE_ALIGNED ) { sl_lsc_alignment_not_possible(sl); sl->statem.emergency = 0; sl->statem.iac_state = SL_STATE_IDLE; }}static inline void sl_iac_sio(sl_t *sl) { switch ( sl->statem.iac_state ) { case SL_STATE_NOT_ALIGNED: sl_timer_stop(t2); if ( sl->statem.emergency ) { sl->statem.t4v = sl->config.t4e; sl_txc_send_sie(sl); } else { sl->statem.t4v = sl->config.t4n; sl_txc_send_sin(sl); } sl_timer_start(t3); sl->statem.iac_state = SL_STATE_ALIGNED; break; case SL_STATE_PROVING: sl_timer_stop(t4); sl->dcalls->aerm_stop(sl); sl_timer_start(t3); sl->statem.iac_state = SL_STATE_ALIGNED; break; }}static inline void sl_iac_sios(sl_t *sl) { switch ( sl->statem.iac_state ) { case SL_STATE_ALIGNED: case SL_STATE_PROVING: sl_timer_stop(t4); /* ok if not running */ sl_lsc_alignment_not_possible(sl); sl->dcalls->aerm_stop(sl); /* ok if not running */ sl_timer_stop(t3); /* ok if not running */ sl->statem.emergency = 0; sl->statem.iac_state = SL_STATE_IDLE; break; }}static inline void sl_lsc_sios(sl_t *sl) { switch ( sl->statem.lsc_state ) { case SL_STATE_ALIGNED_READY: case SL_STATE_ALIGNED_NOT_READY: sl_timer_stop(t1); /* ok to stop if not running */ case SL_STATE_IN_SERVICE: case SL_STATE_PROCESSOR_OUTAGE: sl->statem.failure_reason = SL_FAIL_RECEIVED_SIOS; sl_l3_out_of_service(sl, sl->statem.failure_reason); sl->dcalls->suerm_stop(sl); /* ok to stop if not running */ sl_rc_stop(sl); sl_poc_stop(sl); /* ok if ANSI */ sl_txc_send_sios(sl); sl->statem.emergency = 0; sl->statem.local_processor_outage = 0; sl->statem.remote_processor_outage = 0; /* ok if ITU */ sl->statem.lsc_state = SL_STATE_OUT_OF_SERVICE; break; }}static inline void sl_lsc_no_processor_outage(sl_t* sl){ if ( sl->statem.lsc_state == SL_STATE_PROCESSOR_OUTAGE ) { sl->statem.processor_outage = 0; if ( !sl->statem.l3_indication_received ) return; sl->statem.l3_indication_received = 0; sl_txc_send_msu(sl); sl->statem.local_processor_outage = 0; sl_rc_accept_msu_fisu(sl); sl->statem.lsc_state = SL_STATE_IN_SERVICE; }}static inline void sl_poc_remote_processor_recovered(sl_t* sl){ switch ( sl->statem.poc_state ) { case SL_STATE_REMOTE_PROCESSOR_OUTAGE: sl_lsc_no_processor_outage(sl); sl->statem.poc_state = SL_STATE_IDLE; return; case SL_STATE_BOTH_PROCESSORS_OUT: sl->statem.poc_state = SL_STATE_LOCAL_PROCESSOR_OUTAGE; return; }}static inline void sl_lsc_fisu_msu_received(sl_t *sl) { switch (sl->statem.lsc_state ) { case SL_STATE_ALIGNED_READY: sl_l3_in_service(sl); if ( sl->option.pvar == SS7_PVAR_ITUT_93 ) sl_rc_accept_msu_fisu(sl); /* unnecessary */ sl_timer_stop(t1); sl_txc_send_msu(sl); sl->statem.lsc_state = SL_STATE_IN_SERVICE; return; case SL_STATE_ALIGNED_NOT_READY: sl_l3_in_service(sl); sl_timer_stop(t1); sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; case SL_STATE_PROCESSOR_OUTAGE: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_poc_remote_processor_recovered(sl); sl_l3_remote_processor_recovered(sl); return; case SS7_PVAR_ANSI_92: sl->statem.remote_processor_outage = 0; sl_l3_remote_processor_recovered(sl); return; default: /* * A deviation from the SDLs has been * placed here to limit the number of * remote processor recovered * indications which are delivered to * L3. One indication is sufficient. */ if ( sl->statem.remote_processor_outage ) { sl->statem.remote_processor_outage = 0; sl_l3_remote_processor_recovered(sl); } return; } }}static inline void sl_poc_remote_processor_outage(sl_t* sl){ switch ( sl->statem.poc_state ) { case SL_STATE_IDLE: sl->statem.poc_state = SL_STATE_REMOTE_PROCESSOR_OUTAGE; return; case SL_STATE_LOCAL_PROCESSOR_OUTAGE: sl->statem.poc_state = SL_STATE_BOTH_PROCESSORS_OUT; return; }}static inline void sl_lsc_sib(sl_t *sl){ switch ( sl->statem.lsc_state ) { case SL_STATE_IN_SERVICE: case SL_STATE_PROCESSOR_OUTAGE: sl_txc_sib_received(sl); break; }}static inline void sl_lsc_sipo(sl_t *sl) { switch ( sl->statem.lsc_state ) { case SL_STATE_ALIGNED_READY: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_timer_stop(t1); sl_l3_remote_processor_outage(sl); sl_poc_remote_processor_outage(sl); sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; case SS7_PVAR_ANSI_92: sl_timer_stop(t1); sl_l3_remote_processor_outage(sl); sl->statem.remote_processor_outage = 1; sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; } case SL_STATE_ALIGNED_NOT_READY: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_l3_remote_processor_outage(sl); sl_poc_remote_processor_outage(sl); sl_timer_stop(t1); sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; case SS7_PVAR_ANSI_92: sl_l3_remote_processor_outage(sl); sl->statem.remote_processor_outage = 1; sl_timer_stop(t1); sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; } case SL_STATE_IN_SERVICE: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_txc_send_fisu(sl); sl_l3_remote_processor_outage(sl); sl_poc_remote_processor_outage(sl); sl->statem.processor_outage = 1; /* remote? */ sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; case SS7_PVAR_ANSI_92: sl_txc_send_fisu(sl); sl_l3_remote_processor_outage(sl); sl->statem.remote_processor_outage = 1; sl_rc_align_fsnx(sl); sl_cc_stop(sl); sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; } case SL_STATE_PROCESSOR_OUTAGE: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_l3_remote_processor_outage(sl); sl_poc_remote_processor_outage(sl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -