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

📄 sdt.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
	return rx_table_valueN(state, byte, 8);}/* *  TX (Transmit) Table: *  ----------------------------------- *  There is one TX table for 8-bit (octet) output values.  The table has 256 *  entries and is used to perform, for one sample, zero insertion on frame *  bits for the transmitted bitstream.  It is the reponsiblity of the SDL *  driver to perform 8-bit to 7-bit conversion to DS0A. */STATIC voidtx_table_generate(void){	int j, k;	for (j = 0; j < SDT_TX_STATES; j++)		for (k = 0; k < 256; k++)			*tx_index8(j, k) = tx_table_value(j, k);}/* *  RX (Received) Tables: *  ----------------------------------- *  There is one RX table for 8 bit (octet) values.  The table has 256 entries *  and is used to perform, for one sample, zero deletion, abort detection, *  flag detection and residue calculation on the received bitstream.  The SDL *  driver is responsible for performing 7-bit to 8-bit conversion before *  delivering bits to the SDT. */STATIC voidrx_table_generate(void){	int j, k;	for (j = 0; j < SDT_RX_STATES; j++)		for (k = 0; k < 256; k++)			*rx_index8(j, k) = rx_table_value(j, k);}/* *  BC (CRC) Tables: *  ----------------------------------- *  CRC table organization:  This is a CRC table which contains lookups for *  all bit lengths less than or equal to 8.  There are 512 entries.  The *  first 256 entries are for 8-bit bit lengths, the next 128 entries are for *  7-bit bit lengths, the next 64 entries for 6-bit bit lengths, etc. */STATIC voidbc_table_generate(void){	int pos = 0, bit_string, bit_length = 8, bit_mask = 0x100;	do {		for (bit_string = 0; bit_string < bit_mask; bit_string++, pos++)			bc_table[pos] = bc_table_value(bit_string, bit_length);		bit_length--;	} while ((bit_mask >>= 1));}/* *  Table allocation *  ------------------------------------------------------------------------- */STATIC intsdt_init_tables(void){	size_t length;	length = SDT_CRC_TABLE_LENGTH * sizeof(bc_entry_t);	for (bc_order = 0; PAGE_SIZE << bc_order < length; bc_order++) ;	if (!(bc_table = (bc_entry_t *) __get_free_pages(GFP_KERNEL, bc_order))) {		cmn_err(CE_PANIC, "%s: Cannot allocate bc_table\n", __FUNCTION__);		goto bc_failed;	}	printd(("sdt: allocated BC table size %u kernel pages\n", 1 << bc_order));	bc_table_generate();	printd(("sdt: generated BC table\n"));	length = SDT_TX_TABLE_LENGTH * sizeof(tx_entry_t);	for (tx_order = 0; PAGE_SIZE << tx_order < length; tx_order++) ;	if (!(tx_table = (tx_entry_t *) __get_free_pages(GFP_KERNEL, tx_order))) {		cmn_err(CE_PANIC, "%s: Cannot allocate tx_table\n", __FUNCTION__);		goto tx_failed;	}	printd(("sdt: allocated Tx table size %u kernel pages\n", 1 << tx_order));	tx_table_generate();	printd(("sdt: generated 8-bit Tx table\n"));	length = SDT_RX_TABLE_LENGTH * sizeof(rx_entry_t);	for (rx_order = 0; PAGE_SIZE << rx_order < length; rx_order++) ;	if (!(rx_table = (rx_entry_t *) __get_free_pages(GFP_KERNEL, rx_order))) {		cmn_err(CE_PANIC, "%s: Cannot allocate rx_table\n", __FUNCTION__);		goto rx_failed;	}	printd(("sdt: allocated Rx table size %u kernel pages\n", 1 << rx_order));	rx_table_generate();	printd(("sdt: generated 8-bit Rx table\n"));	return (0);      rx_failed:	free_pages((unsigned long) tx_table, tx_order);	tx_order = 0;      tx_failed:	free_pages((unsigned long) bc_table, bc_order);	bc_order = 0;      bc_failed:	return (-ENOMEM);}STATIC intsdt_term_tables(void){	free_pages((unsigned long) bc_table, bc_order);	printd(("sdt: freed BC table kernel pages\n"));	free_pages((unsigned long) tx_table, tx_order);	printd(("sdt: freed Tx table kernel pages\n"));	free_pages((unsigned long) rx_table, rx_order);	printd(("sdt: freed Rx table kernel pages\n"));	return (0);}/* *  ======================================================================== * *  EVENTS * *  ======================================================================== *//* *  RX WAKEUP *  ----------------------------------- *  This is called before the queue service routine unlocks the queue.  We *  must check if back-enabling has occured on an empty read queue. */STATIC streamscall voidsdt_rx_wakeup(queue_t *q){	(void) q;	return;}/* *  TX WAKEUP *  ----------------------------------- *  This is called before the queue service routine unlocks the queue. *  sdt_tx_block will pull data from the queue as necessary. */STATIC streamscall voidsdt_tx_wakeup(queue_t *q){	struct sdt *s = SDT_PRIV(q);	if ((s->i_state == LMI_ENABLED) && (s->statem.daedt_state != SDT_STATE_IDLE))		sdt_tx_block(q, s);	return;}/* *  ------------------------------------------------------------------------- * *  Timer Events * *  ------------------------------------------------------------------------- *//* *  T8 TIMEOUT *  ----------------------------------- */STATIC intsdt_t8_timeout(struct sdt *s){	queue_t *q = NULL;	int err;	if (s->statem.eim_state == SDT_STATE_MONITORING) {		sdt_timer_start(s, t8);		if (s->statem.su_received) {			s->statem.su_received = 0;			if (!s->statem.interval_error) {				if ((s->statem.Ce -= s->config.De) < 0)					s->statem.Ce = 0;				return (QR_DONE);			}		}		s->statem.Ce += s->config.Ue;		if (s->statem.Ce > s->config.Te) {			if ((err = sdt_lsc_link_failure_ind(q, s))) {				s->statem.Ce -= s->config.Ue;				return (err);			}			s->statem.eim_state = SDT_STATE_IDLE;		}		s->statem.interval_error = 0;	}	return (QR_DONE);}/* *  ------------------------------------------------------------------------- * *  LM User -> LM Provider Primitives * *  ------------------------------------------------------------------------- *//* *  LMI_INFO_REQ: *  ----------------------------------- *  We just pass info request along and service them on reply from the lower *  level. */STATIC intsdt_info_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_info_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	return (QR_PASSFLOW);      emsgsize:	return lmi_error_ack(q, s, LMI_INFO_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_ATTACH_REQ: *  ----------------------------------- *  We do not perform attaches as this is a software SDT.  The SDT selected is *  the current SDT.  We do, however, pass these along to the lower level if *  the lower level is of the correct style. */STATIC intsdt_attach_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_attach_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_style != LMI_STYLE2)		goto eopnotsupp;	if (s->i_state != LMI_UNATTACHED)		goto outstate;	if (mp->b_wptr < mp->b_rptr + sizeof(*p) + 2)		goto badppa;	s->i_state = LMI_ATTACH_PENDING;	return (QR_PASSFLOW);      badppa:	ptrace(("%s: %p: PROTO: bad ppa (too short)\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_BADPPA, EMSGSIZE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_OUTSTATE, EPROTO);      eopnotsupp:	ptrace(("%s: %p: PROTO: primitive not supported for style\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_NOTSUPP, EOPNOTSUPP);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ATTACH_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_DETACH_REQ: *  ----------------------------------- *  We do not perform detaches as this is a software SDT.  The SDT selected is *  the current SDT.  We do, however, pass these along to the lower level if *  the lower level is of the correct style. */STATIC intsdt_detach_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_detach_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_style != LMI_STYLE2)		goto eopnotsupp;	if (s->i_state != LMI_DISABLED)		goto outstate;	s->i_state = LMI_DETACH_PENDING;	return (QR_PASSFLOW);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_OUTSTATE, EPROTO);      eopnotsupp:	ptrace(("%s: %p: PROTO: primitive not supported for style\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_NOTSUPP, EOPNOTSUPP);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DETACH_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_ENABLE_REQ: *  ----------------------------------- *  We must allow the SDL first crack at enabling before we fully enable.  We *  commit the enable when the LMI_ENABLE_CON is returned from below. */STATIC intsdt_enable_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_enable_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_DISABLED)		goto outstate;	s->i_state = LMI_ENABLE_PENDING;	return (QR_PASSFLOW);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ENABLE_REQ, LMI_OUTSTATE, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_ENABLE_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_DISABLE_REQ: *  ----------------------------------- *  We must allow the SDL first carack an disabling before we fully disable. *  We commit the disable when the LMI_DISABLE_CON is returned from below. */STATIC intsdt_disable_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_disable_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state == LMI_UNUSABLE)		goto eagain;	if (s->i_state != LMI_ENABLED)		goto outstate;	s->i_state = LMI_DISABLE_PENDING;	return (QR_PASSFLOW);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DISABLE_REQ, LMI_OUTSTATE, EPROTO);      eagain:	ptrace(("%s: %p: INFO: waiting for streams to become usable\n", MOD_NAME, s));	return (-EAGAIN);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_DISABLE_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  LMI_OPTMGMT_REQ: *  ----------------------------------- */STATIC intsdt_optmgmt_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	lmi_optmgmt_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	return (QR_PASSFLOW);      emsgsize:	(void) s;	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return lmi_error_ack(q, s, LMI_OPTMGMT_REQ, LMI_PROTOSHORT, EMSGSIZE);}/* *  ------------------------------------------------------------------------- * *  SDT User -> SDT Provider Primitives * *  ------------------------------------------------------------------------- *//* *  M_DATA *  ----------------------------------- */STATIC intsdt_send_data(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	int len, hlen;	if (s->i_state != LMI_ENABLED)		goto discard;	if (s->statem.daedt_state == SDT_STATE_IDLE)		goto discard;	/* ignore tramsmissions when daedt shut down */	len = msgdsize(mp);	hlen = (s->option.popt & SS7_POPT_XSN) ? 6 : 3;	if (len < hlen || len > hlen + s->config.m + 1)		goto eproto;	/* 	   let tx_wakeup pull from the queue */	return (-EAGAIN);      eproto:	swerr();		/* length violation, error out stream */	return m_error(q, s, EPROTO);      discard:	return (QR_DONE);	/* silent discard */}/* *  SDT_DAEDT_TRANSMISSION_REQ: *  ----------------------------------- *  This is the non-preferred way of sending data.  It is preferred that *  M_DATA blocks are used (above).  We just strip off the M_PROTO and requeue *  only the M_DATA blocks. */STATIC intsdt_daedt_transmission_req(queue_t *q, mblk_t *mp){	mblk_t *dp;	if ((dp = mp->b_cont) && dp->b_datap->db_type == M_DATA) {		trace();		return (QR_STRIP);	}	return (-EPROTO);}/* *  SDT_DAEDT_START_REQ: *  ----------------------------------- */STATIC intsdt_daedt_start_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	sdt_daedt_start_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->statem.daedt_state == SDT_STATE_IDLE)		s->statem.daedt_state = SDT_STATE_IN_SERVICE;	return (QR_DONE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return (-EMSGSIZE);}/* *  SDT_DAEDR_START_REQ: *  ----------------------------------- */STATIC intsdt_daedr_start_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	sdt_daedr_start_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->statem.daedr_state == SDT_STATE_IDLE)		s->statem.daedr_state = SDT_STATE_IN_SERVICE;	return (QR_DONE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return (-EMSGSIZE);}/* *  SDT_AERM_START_REQ: *  ----------------------------------- */STATIC intsdt_aerm_start_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	sdt_aerm_start_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->statem.aerm_state != SDT_STATE_MONITORING) {		s->statem.Ca = 0;		s->statem.aborted_proving = 0;		s->statem.aerm_state = SDT_STATE_MONITORING;	}	return (QR_DONE);      outstate:	ptrace(("%s: %p: PROTO: out of state\n", MOD_NAME, s));	return m_error(q, s, EPROTO);      emsgsize:	ptrace(("%s: %p: PROTO: M_PROTO block too short\n", MOD_NAME, s));	return (-EMSGSIZE);}/* *  SDT_AERM_STOP_REQ: *  ----------------------------------- */STATIC intsdt_aerm_stop_req(queue_t *q, mblk_t *mp){	struct sdt *s = SDT_PRIV(q);	sdt_aerm_stop_req_t *p = (typeof(p)) mp->b_rptr;	if (mp->b_wptr < mp->b_rptr + sizeof(*p))		goto emsgsize;	if (s->i_state != LMI_ENABLED)		goto outstate;	if (s->statem.aerm_state != SDT_STATE_IDLE) {		s->statem.aerm_state = SDT_STATE_IDLE;		s->statem.Ti = s->config.Tin;	}	return (QR_DONE

⌨️ 快捷键说明

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