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

📄 sdt.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
					sdt_tx_bitstuff(tx, tx->bcc & 0x00ff);					tx->mode = TX_MODE_BCC;				}				goto drain_rbits;			case TX_MODE_BCC:				/* 				   add 2nd bcc byte */				sdt_tx_bitstuff(tx, tx->bcc >> 8);				stats->tx_sus++;				tx->mode = TX_MODE_FLAG;				goto next_message;			}			swerr();		}		putnext(q, bp);	}}#if 0/* *  RX COMPRESS *  ---------------------------------------- *  Check for RX compression.  Returns 1 when compression in effect, 0 *  otherwise. */STATIC INLINE intsdt_rx_compress(queue_t *q, struct sdt *s, mblk_t *mp){	mblk_t *cp = s->rx.cmp;	int len1 = msgdsize(mp);	int len2 = cp ? msgdsize(cp) : 0;	int len_max = (s->option.popt & SS7_POPT_XSN) ? 8 : 5;	if (len1 > len_max) {		// printd(("sdt: len1 = %d > len_max = %d\n", len1, len_max));		goto failure;	}	if (len1 != len2) {		// printd(("sdt: len1 = %d != len2 = %d\n", len1, len2));		goto failure;	} else {		int pos;		// pullupmsg(mp, len1);		for (pos = 0; pos < len1; pos++)			if (cp->b_rptr[pos] != mp->b_rptr[pos]) {				// printd(("sdt: mismatch at byte %d\n", pos + 1));				goto failure;			}		return (1);	}      failure:	return (0);}#endif/* *  RX LINKB *  ---------------------------------------- *  Link a buffer to existing message or create new message with buffer. */STATIC INLINE voidsdt_rx_linkb(sdt_path_t * rx){	if (rx->msg)		linkb(rx->msg, rx->nxt);	else		rx->msg = rx->nxt;	rx->nxt = NULL;	return;}#define RX_MODE_HUNT	0	/* hunting for flags */#define RX_MODE_SYNC	1	/* between frames */#define RX_MODE_MOF	2	/* middle of frame *//* *  RX BLOCK *  ---------------------------------------- *  Process a receive block for a channel or span.  We process all of the *  octets in the receive block.  Any complete messages will be delivered to *  the upper layer if the upper layer is not congested.  If the upper layer *  is congested we discard the message and indicate receive congestion.  The *  upper layer should be sensitive to its receive queue backlog and start *  sending SIB when required.  We do not use backenabling from the upper *  layer.  We merely start discarding complete messages when the upper layer *  is congested. */STATIC voidsdt_rx_block(queue_t *q, struct sdt *s, mblk_t *dp){	register sdt_path_t *rx = &s->rx;	sdt_stats_t *stats = &s->stats;	while (dp->b_rptr < dp->b_wptr) {		rx_entry_t *r;#if 0		if (s->config.iftype != SDL_TYPE_DS0A)#endif			r = rx_index8(rx->state, *dp->b_rptr++);#if 0		else			r = rx_index7(rx->state, *dp->b_rptr++);#endif		rx->state = r->state;		switch (rx->mode) {		case RX_MODE_MOF:			if (!r->sync && r->bit_length) {				rx->residue |= r->bit_string << rx->rbits;				rx->rbits += r->bit_length;			}			if (!r->flag) {				if (r->hunt || r->idle)					goto aborted;				while (rx->rbits > 16) {					if (rx->nxt && rx->nxt->b_wptr >= rx->nxt->b_datap->db_lim)						sdt_rx_linkb(rx);					if (!rx->nxt && !(rx->nxt = allocb(FASTBUF, BPRI_HI)))						goto buffer_overflow;					rx->bcc = (rx->bcc >> 8)					    ^ bc_table[(rx->bcc ^ rx->residue) & 0x00ff];					*(rx->nxt->b_wptr)++ = rx->residue;					stats->rx_bytes++;					rx->residue >>= 8;					rx->rbits -= 8;					rx->bytes++;					if (!(s->option.popt & SS7_POPT_XSN)) {						if (rx->bytes > s->config.m + 1 + 3)							goto frame_too_long;					} else {						if (rx->bytes > s->config.m + 1 + 6)							goto frame_too_long;					}				}			} else {				uint li;				if (rx->rbits != 16)					goto residue_error;				if (rx->bcc != (rx->residue & 0xffff))					goto crc_error;				if (!(s->option.popt & SS7_POPT_XSN)) {					if (rx->bytes < 3)						goto frame_too_short;					sdt_rx_linkb(rx);					li = (rx->msg->b_rptr[2] & 0x3f) + 3;					if (rx->bytes != li && (li != 0x3f + 3 || rx->bytes < li))						goto length_error;				} else {					if (rx->bytes < 6)						goto frame_too_short;					sdt_rx_linkb(rx);					li = (((rx->msg->b_rptr[5] << 8)					       | rx->msg->b_rptr[4]) & 0x1ff) + 6;					if (rx->bytes != li && (li != 0x1ff + 6 || rx->bytes < li))						goto length_error;				}				stats->rx_sus++;				sdt_daedr_received_bits(q, s, xchg(&rx->msg, NULL));			      new_frame:				rx->mode = RX_MODE_SYNC;				if (r->sync) {				      begin_frame:					if (r->bit_length) {						rx->mode = RX_MODE_MOF;						rx->residue = r->bit_string;						rx->rbits = r->bit_length;						rx->bytes = 0;						rx->bcc = 0x00ff;					}				}			}			break;		      frame_too_long:			stats->rx_frame_too_long++;			stats->rx_frame_errors++;			goto abort_frame;		      buffer_overflow:			stats->rx_buffer_overflows++;			goto abort_frame;		      aborted:			stats->rx_aborts++;			stats->rx_frame_errors++;			goto abort_frame;		      length_error:			stats->rx_length_error++;			goto abort_frame;		      frame_too_short:			stats->rx_frame_too_short++;			stats->rx_frame_errors++;			goto abort_frame;		      crc_error:			stats->rx_crc_errors++;			goto abort_frame;		      residue_error:			stats->rx_residue_errors++;			stats->rx_frame_errors++;			goto abort_frame;		      abort_frame:			if (rx->nxt)				freemsg(xchg(&rx->nxt, NULL));			if (rx->msg)				freemsg(xchg(&rx->msg, NULL));			stats->rx_sus_in_error++;			sdt_daedr_su_in_error(q, s);			if (r->flag)				goto new_frame;			rx->mode = RX_MODE_HUNT;			stats->rx_sync_transitions++;			s->rx_octets = 0;			break;		case RX_MODE_SYNC:			if (!r->hunt && !r->idle)				goto begin_frame;			rx->mode = RX_MODE_HUNT;			stats->rx_sync_transitions++;			s->rx_octets = 0;			break;		case RX_MODE_HUNT:			if (!r->flag) {				if ((++(s->rx_octets)) >= s->config.N) {					stats->rx_sus_in_error++;					sdt_daedr_su_in_error(q, s);					s->rx_octets -= s->config.N;				}				stats->rx_bits_octet_counted += 8;				break;			}			stats->rx_sync_transitions++;			goto new_frame;		default:			swerr();			goto abort_frame;		}	}}/* *  ------------------------------------------------------------------------- * *  Table allocation and generation * *  ------------------------------------------------------------------------- *  All Soft HDLC lookup stables are generated at module load time.  This *  permits the tables to be page-aligned in kernel memory for maximum cache *  performance. *//* *  BC (Block Check) CRC Table Entries: *  ----------------------------------- *  RC tables perform CRC calculation on received bits after zero deletion and *  delimitation. */STATIC bc_entry_tbc_table_value(int bit_string, int bit_length){	int pos;	for (pos = 0; pos < bit_length; pos++) {		if (bit_string & 0x1)			bit_string = (bit_string >> 1) ^ 0x8408;		else			bit_string >>= 1;	}	return (bit_string);}/* *  TX (Transmission) Table Entries: *  ----------------------------------- *  TX table performs zero insertion on frame and CRC bit streams. */STATIC tx_entry_ttx_table_valueN(int state, uint8_t byte, int len){	tx_entry_t result = { 0, };	int bit_mask = 1;	result.state = state;	result.bit_length = 0;	while (len--) {		if (byte & 0x1) {			result.bit_string |= bit_mask;			if (result.state++ == 4) {				result.state = 0;				result.bit_length++;				bit_mask <<= 1;			}		} else			result.state = 0;		bit_mask <<= 1;		byte >>= 1;	}	return result;}STATIC tx_entry_ttx_table_value(int state, uint8_t byte){	return tx_table_valueN(state, byte, 8);}/* *  RX (Receive) Table Entries: *  ----------------------------------- *  RX table performs zero deletion, flag and abort detection, BOF and EOF *  detection and residue on received bit streams. */STATIC rx_entry_trx_table_valueN(int state, uint8_t byte, int len){	rx_entry_t result = { 0, };	int bit_mask = 1;	result.state = state;	while (len--) {		switch (result.state) {		case 0:	/* */			if (result.flag && !result.sync) {				bit_mask = 1;				result.bit_string = 0;				result.bit_length = 0;				result.sync = 1;			}			if (byte & 0x1) {				result.state = 8;			} else {				result.state = 1;			}			break;		case 1:	/* 0 */			if (byte & 0x1) {				result.state = 2;			} else {				bit_mask <<= 1;				result.bit_length += 1;				result.state = 1;			}			break;		case 2:	/* 01 */			if (byte & 0x1) {				result.state = 3;			} else {				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 2;				result.state = 1;			}			break;		case 3:	/* 011 */			if (byte & 0x1) {				result.state = 4;			} else {				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 3;				result.state = 1;			}			break;		case 4:	/* 0111 */			if (byte & 0x1) {				result.state = 5;			} else {				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 4;				result.state = 1;			}			break;		case 5:	/* 01111 */			if (byte & 0x1) {				result.state = 6;			} else {				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 5;				result.state = 1;			}			break;		case 6:	/* 011111 */			if (byte & 0x1) {				result.state = 7;			} else {				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 6;				result.state = 0;			}			break;		case 7:	/* 0111111 */			if (byte & 0x1) {				result.sync = 0;				result.flag = 0;				result.hunt = 1;				result.state = 12;			} else {				result.sync = 0;				result.flag = 1;				result.hunt = 0;				result.idle = 0;				result.state = 0;			}			break;		case 8:	/* 1 */			if (byte & 0x1) {				result.state = 9;			} else {				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 1;				result.state = 1;			}			break;		case 9:	/* 11 */			if (byte & 0x1) {				result.state = 10;			} else {				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 2;				result.state = 1;			}			break;		case 10:	/* 111 */			if (byte & 0x1) {				result.state = 11;			} else {				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 3;				result.state = 1;			}			break;		case 11:	/* 1111 */			if (byte & 0x1) {				result.state = 12;			} else {				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 4;				result.state = 1;			}			break;		case 12:	/* 11111 */			if (byte & 0x1) {				result.state = 13;			} else {				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_string |= bit_mask;				bit_mask <<= 1;				result.bit_length += 5;				result.state = 0;			}			break;		case 13:	/* 111111 */			if (byte & 0x1) {				result.hunt = 1;				result.sync = 0;				result.idle = 1;				result.flag = 0;				result.state = 12;			} else {				result.sync = 0;				result.hunt = 0;				result.idle = 0;				result.flag = 1;				result.state = 0;			}			break;		}		byte >>= 1;	}	return result;}STATIC rx_entry_trx_table_value(int state, uint8_t byte){

⌨️ 快捷键说明

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