📄 sl_sm.h
字号:
switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: return; case SS7_PVAR_ANSI_92: sl_l3_rtb_cleared(sl); sl->statem.local_processor_outage = 0; sl_txc_send_fisu(sl); sl->statem.lsc_state = SL_STATE_ALIGNED_READY; return; } case SL_STATE_PROCESSOR_OUTAGE: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_txc_flush_buffers(sl); sl->statem.l3_indication_received = 1; if ( sl->statem.processor_outage ) 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; return; case SS7_PVAR_ANSI_92: sl->statem.local_processor_outage = 0; sl_rc_clear_rb(sl); sl_rc_accept_msu_fisu(sl); sl_txc_send_fisu(sl); sl_txc_clear_tb(sl); sl_txc_clear_rtb(sl); return; } }}static inline void sl_lsc_continue(sl_t* sl, mblk_t *mp){ if ( sl->statem.lsc_state == SL_STATE_PROCESSOR_OUTAGE ) { if ( sl->statem.processor_outage ) 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_local_processor_recovered(sl_t* sl){ switch ( sl->statem.poc_state ) { case SL_STATE_LOCAL_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_REMOTE_PROCESSOR_OUTAGE; return; }}#define sl_lsc_resume sl_lsc_local_processor_recoveredstatic inline void sl_lsc_local_processor_recovered(sl_t *sl) { switch ( sl->statem.lsc_state ) { case SL_STATE_OUT_OF_SERVICE: sl->statem.local_processor_outage = 0; return; case SL_STATE_INITIAL_ALIGNMENT : sl->statem.local_processor_outage = 0; return; case SL_STATE_ALIGNED_READY : return; case SL_STATE_ALIGNED_NOT_READY : if ( sl->option.pvar != SS7_PVAR_ANSI_92 ) sl_poc_local_processor_recovered(sl); sl->statem.local_processor_outage = 0; sl_txc_send_fisu(sl); if ( sl->option.pvar == SS7_PVAR_ITUT_96 ) sl_rc_accept_msu_fisu(sl); sl->statem.lsc_state = SL_STATE_ALIGNED_READY; return; case SL_STATE_PROCESSOR_OUTAGE: switch ( sl->option.pvar ) { case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: sl_poc_local_processor_recovered(sl); sl_rc_retrieve_fsnx(sl); sl_txc_send_fisu(sl); /* note 3: in fisu BSN <= FSNX-1 */ sl->statem.lsc_state = SL_STATE_IN_SERVICE; case SS7_PVAR_ANSI_92: sl->statem.local_processor_outage = 0; sl_rc_accept_msu_fisu(sl); if ( sl->statem.remote_processor_outage ) { sl_txc_send_fisu(sl); sl_l3_remote_processor_outage(sl); return; } sl_txc_send_msu(sl); sl->statem.lsc_state = SL_STATE_IN_SERVICE; return; } }}#define sl_lsc_level_3_failure sl_lsc_local_processor_outagestatic inline void sl_lsc_local_processor_outage(sl_t *sl) { switch ( sl->statem.lsc_state ) { case SL_STATE_OUT_OF_SERVICE: case SL_STATE_INITIAL_ALIGNMENT: sl->statem.local_processor_outage = 1; return; case SL_STATE_ALIGNED_READY: if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) sl->statem.local_processor_outage = 1; else sl_poc_local_processor_outage(sl); sl_txc_send_sipo(sl); if ( sl->option.pvar != SS7_PVAR_ITUT_93 ) /* possible error 93 specs */ sl_rc_reject_msu_fisu(sl); sl->statem.lsc_state = SL_STATE_ALIGNED_NOT_READY; return; case SL_STATE_IN_SERVICE: if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) { sl->statem.local_processor_outage = 1; } else { sl_poc_local_processor_outage(sl); sl->statem.processor_outage = 1; } sl_txc_send_sipo(sl); sl_rc_reject_msu_fisu(sl); if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) { sl_rc_align_fsnx(sl); sl_cc_stop(sl); } sl->statem.lsc_state = SL_STATE_PROCESSOR_OUTAGE; return; case SL_STATE_PROCESSOR_OUTAGE: if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) sl->statem.local_processor_outage = 1; else sl_poc_local_processor_outage(sl); sl_txc_send_sipo(sl); return; }}static inline void sl_iac_emergency(sl_t *sl) { switch ( sl->statem.iac_state ) { case SL_STATE_PROVING: sl_txc_send_sie(sl); sl_timer_stop(t4); sl->statem.t4v = sl->config.t4e; sl->dcalls->aerm_stop(sl); sl->dcalls->aerm_set_tie(sl); sl->dcalls->aerm_start(sl); sl->statem.further_proving = 0; sl_timer_start_t4(t4v); return; case SL_STATE_ALIGNED: sl_txc_send_sie(sl); sl->statem.t4v = sl->config.t4e; return; case SL_STATE_IDLE: case SL_STATE_NOT_ALIGNED: sl->statem.emergency = 1; }}static inline void sl_lsc_emergency(sl_t *sl){ sl->statem.emergency = 1; sl_iac_emergency(sl); /* added to pass Q.781/Test 1.20 */}static inline void sl_lsc_emergency_ceases(sl_t *sl){ sl->statem.emergency = 0;}static inline void sl_iac_start(sl_t *sl) { if ( sl->statem.iac_state == SL_STATE_IDLE ) { sl_txc_send_sio(sl); sl_timer_start(t2); sl->statem.iac_state = SL_STATE_NOT_ALIGNED; }}static inline void sl_txc_start(sl_t *sl) { sl->statem.forced_retransmission = 0; /* ok if basic */ sl->statem.sib_received = 0; sl->statem.Ct = 0; sl->statem.rtb_full = 0; sl->statem.clear_rtb = 0; /* ok if ITU */ if ( sl->option.pvar == SS7_PVAR_ANSI_92 ) { sl->statem.tx.sio = LSSU_SIOS; sl->statem.lssu_available = 1; } sl->statem.msu_inhibited = 0; sl->statem.tx.L.fsn = sl->statem.tx.N.fsn = sl->statem.sn_mask; sl->statem.tx.X.fsn = 0; sl->statem.tx.N.fib = sl->statem.tx.N.bib = sl->statem.ib_mask; sl->statem.tx.F.fsn = 0; sl->statem.Cm = 0; sl->statem.Z = 0; sl->statem.z_ptr = NULL; /* ok if basic */ if ( sl->statem.txc_state == SL_STATE_IDLE ) { if ( sl->option.pvar != SS7_PVAR_ANSI_92 ) sl->statem.lssu_available = 0; sl->dcalls->daedt_start(sl); } sl->statem.txc_state = SL_STATE_SLEEPING; return;}static inline void sl_lsc_start(sl_t *sl){ switch ( sl->statem.lsc_state ) { case SL_STATE_OUT_OF_SERVICE: sl_rc_start(sl); sl_txc_start(sl); /* Note 2 */ if ( sl->statem.emergency ) sl_iac_emergency(sl); sl_iac_start(sl); sl->statem.lsc_state = SL_STATE_INITIAL_ALIGNMENT; }}/* * Note 2: There is a difference here between ANSI_92 and ITUT_93/96 in that * the transmitters in the ANSI_92 case may transmit one or two SIOSs before * transmitting the first SIO of the initial alignment procedure. ITUT will * continue idling FISU or LSSU as before the start, then transmit the first * SIO. These are equivalent. Because the LSC is in the OUT OF SERVICE * state, the transmitters should be idling SIOS anyway. */static inline void sl_lsc_retrieve_bsnt(sl_t *sl){ switch ( sl->statem.lsc_state ) { case SL_STATE_OUT_OF_SERVICE: case SL_STATE_PROCESSOR_OUTAGE: sl_rc_retrieve_bsnt(sl); }}static inline void sl_lsc_retrieval_request_and_fsnc(sl_t *sl, sl_ulong fsnc){ switch ( sl->statem.lsc_state ) { case SL_STATE_OUT_OF_SERVICE: case SL_STATE_PROCESSOR_OUTAGE: sl_txc_retrieval_request_and_fsnc(sl, fsnc); }}/* * This power-on sequence should only be performed once, regardless of how * many times the device driver is opened or closed. This initializes the * transmitters to send SIOS and should never be changed hence. */static inline void sl_lsc_power_on(sl_t *sl) { switch ( sl->statem.lsc_state ) { case SL_STATE_POWER_OFF: sl_txc_start(sl); /* Note 3 */ sl_txc_send_sios(sl); /* not necessary for ANSI */ sl->dcalls->aerm_set_tin(sl); sl->statem.local_processor_outage = 0; sl->statem.emergency = 0; sl->statem.lsc_state = SL_STATE_OUT_OF_SERVICE; }}/* * Note 3: There is a difference here between ANSI_92 and ITUT_93/96 in that * the transmitters in the ITUT case may transmit one or two FISUs before * transmitting SIOS on initial power-up. ANSI will send SIOS on power-up. * ANSI is the correct procedure as transmitters should always idle SIOS on * power-up. *//* * The transmit congestion algorithm is an implementation dependent algorithm * but is suggested as being based on TB and/or RTB buffer occupancy. With * STREAMS we can use octet count buffer occupancy over message count * occupancy, because congestion in transmission is more related to octet * count (because it determines transmission latency). * * We check the total buffer occupancy and apply the necessary congestion * control signal as per configured abatement, onset and discard thresholds. */static void sl_check_congestion(sl_t *sl){ unsigned int occupancy = sl->tb.q_count + sl->rtb.q_count; int old_cong_status = sl->statem.cong_status; int old_disc_status = sl->statem.disc_status; int multi = sl->option.popt & SS7_POPT_MPLEV; switch (sl->statem.cong_status) { case 0: if ( occupancy >= sl->config.tb_onset_1 ) { sl->statem.cong_status = 1; if ( occupancy >= sl->config.tb_discd_1 ) { sl->statem.disc_status = 1; if ( !multi ) break; if ( occupancy >= sl->config.tb_onset_2 ) { sl->statem.cong_status = 2; if ( occupancy >= sl->config.tb_discd_2 ) { sl->statem.disc_status = 2; if ( occupancy >= sl->config.tb_onset_3 ) { sl->statem.cong_status = 3; if ( occupancy >= sl->config.tb_discd_3 ) { sl->statem.disc_status = 3; } } } } } } break; case 1: if ( occupancy < sl->config.tb_abate_1 ) { sl->statem.cong_status = 0; sl->statem.disc_status = 0; } else { if ( !multi ) break; if ( occupancy >= sl->config.tb_onset_2 ) { sl->statem.cong_status = 2; if ( occupancy >= sl->config.tb_discd_2 ) { sl->statem.disc_status = 2; if ( occupancy >= sl->config.tb_onset_3 ) { sl->statem.cong_status = 3; if ( occupancy >= sl->config.tb_discd_3 ) { sl->statem.disc_status = 3; } } } } } break; case 2: if ( !multi ) { sl->statem.cong_status = 1; sl->statem.disc_status = 1; break; } if ( occupancy < sl->config.tb_abate_2 ) { sl->statem.cong_status = 1; sl->statem.disc_status = 1; if ( occupancy < sl->config.tb_abate_1 ) { sl->statem.cong_status = 0; sl->statem.disc_status = 0; } } else if ( occupancy >= sl->config.tb_onset_3 ) { sl->statem.cong_status = 3; if ( occupancy >= sl->config.tb_discd_3 ) { sl->statem.disc_status = 3; } } break; case 3: if ( !multi ) { sl->statem.cong_status = 1; sl->statem.disc_status = 1; break; } if ( occupancy < sl->config.tb_abate_3 ) { sl->statem.cong_status = 2; sl->statem.disc_status = 2; if ( occupancy < sl->config.tb_abate_2 ) { sl->statem.cong_status = 1; sl->statem.disc_status = 1; if ( occupancy < sl->config.tb_abate_1 ) { sl->statem.cong_status = 0; sl->statem.disc_status = 0; } } } break; } if ( sl->statem.cong_status != old_cong_status || sl->statem.disc_status != old_disc_status ) { if ( sl->statem.cong_status < old_cong_status ) sl_l3_link_congestion_ceased(sl, sl->statem.cong_status, sl->statem.disc_status); else { if ( sl->statem.cong_status > old_cong_status ) { if ( sl->notify.events & SL_EVT_CONGEST_ONSET_IND && !sl->stats.sl_cong_onset_ind[sl->statem.cong_status]++ ) { sl_l3_link_congested(sl, sl->statem.cong_status, sl->statem.disc_status); return; } } else { if ( sl->notify.events & SL_EVT_CONGEST_DISCD_IND && !sl->stats.sl_cong_discd_ind[sl->statem.disc_status]++ ) { sl_l3_link_congested(sl, sl->statem.cong_status, sl->statem.disc_status); return; } } sl_l3_link_congested(sl, sl->statem.cong_status, sl->statem.disc_status); } }}static inline void sl_txc_message_for_transmission(sl_t *sl, mblk_t *mp){ bufq_queue(&sl->tb, mp); sl->statem.Cm++; sl_check_congestion(sl); sl_daedt_transmitter_wakeup(sl);}static inline void sl_lsc_pdu(sl_t *sl, mblk_t *mp){ mblk_t *md; if (mp->b_datap->db_type != M_DATA) { md = unlinkb(mp); freemsg(mp); } else md = mp; if ( md ) { int hlen = (sl->option.popt&SS7_POPT_XSN)?6:3; if ( md->b_datap->db_type != M_DATA ) { freemsg(md); return; } if ( (md->b_datap->db_base - md->b_rptr) >= hlen ) { md->b_rptr -= hlen; } else { if ( (md->b_datap->db_lim - md->b_wptr) >= hlen ) { memmove(md->b_rptr+hlen, md->b_rptr, md->b_wptr - md->b_rptr); md->b_wptr += hlen; } else {#if 0 /* this code doesn't seem to work later on... */ mblk_t *mh = allocb(hlen, BPRI_HI); if ( mh ) { mh->b_datap->db_type = M_DATA; mh->b_wptr += hlen; linkb(mh, md); md = mh; } else { freemsg(md); return; }#else int len = md->b_wptr-md->b_rptr; mblk_t *m2 = allocb(hlen+len, BPRI_HI); if ( m2 ) { bcopy(md->b_rptr, m2->b_rptr+hlen, len); m2->b_wptr = m2->b_rptr + hlen + len; md = m2; } else { freemsg(md); return; }#endif } } sl_txc_message_for_transmission(sl, md); }}/* * Calls from Management: * * sl_lsc_power_on * sl_lsc_local_processor_outage * sl_lsc_level_3_failure */#endif __SL_SM_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -