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

📄 mtp_tpi.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
{	return (mtp_chk_state(mtp, ~mask));}#ifndef TS_NOSTATES#define TS_NOSTATES (TS_WACK_DREQ11 + 1)#endif/* *  TLI interface state flags */#define TSF_UNBND	( 1 << TS_UNBND		)#define TSF_WACK_BREQ	( 1 << TS_WACK_BREQ	)#define TSF_WACK_UREQ	( 1 << TS_WACK_UREQ	)#define TSF_IDLE	( 1 << TS_IDLE		)#define TSF_WACK_OPTREQ	( 1 << TS_WACK_OPTREQ	)#define TSF_WACK_CREQ	( 1 << TS_WACK_CREQ	)#define TSF_WCON_CREQ	( 1 << TS_WCON_CREQ	)#define TSF_WRES_CIND	( 1 << TS_WRES_CIND	)#define TSF_WACK_CRES	( 1 << TS_WACK_CRES	)#define TSF_DATA_XFER	( 1 << TS_DATA_XFER	)#define TSF_WIND_ORDREL	( 1 << TS_WIND_ORDREL	)#define TSF_WREQ_ORDREL	( 1 << TS_WREQ_ORDREL	)#define TSF_WACK_DREQ6	( 1 << TS_WACK_DREQ6	)#define TSF_WACK_DREQ7	( 1 << TS_WACK_DREQ7	)#define TSF_WACK_DREQ9	( 1 << TS_WACK_DREQ9	)#define TSF_WACK_DREQ10	( 1 << TS_WACK_DREQ10	)#define TSF_WACK_DREQ11	( 1 << TS_WACK_DREQ11	)#define TSF_NOSTATES	( 1 << TS_NOSTATES	)#define TSF_WACK_DREQ	(TSF_WACK_DREQ6 \			|TSF_WACK_DREQ7 \			|TSF_WACK_DREQ9 \			|TSF_WACK_DREQ10 \			|TSF_WACK_DREQ11)#define TSF_WACK	(TSF_WACK_BREQ \			|TSF_WACK_UREQ \			|TSF_WACK_OPTREQ \			|TSF_WACK_CREQ \			|TSF_WACK_CRES \			|TSF_WACK_DREQ6 \			|TSF_WACK_DREQ7 \			|TSF_WACK_DREQ9 \			|TSF_WACK_DREQ10 \			|TSF_WACK_DREQ11)static voidmtp_bind(struct mtp *mtp, struct mtp_addr *src){	if (src) {		mtp->src = *src;		mtp->src_len = sizeof(*src);	}	return;}static voidmtp_connect(struct mtp *mtp, struct mtp_addr *dst){	if (dst) {		mtp->dst = *dst;		mtp->dst_len = sizeof(*dst);	}	return;}static voidmtp_unbind(struct mtp *mtp){	mtp->src_len = 0;	return;}static voidmtp_disconnect(struct mtp *mtp){	mtp->dst_len = 0;	return;}/* *  ========================================================================= * *  PRIMITIVES * *  ========================================================================= *//* *  Primitives sent upstream *  ------------------------------------------------------------------------- *//** * m_error: - issue an M_ERROR message upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @err: error value */static intm_error(struct mtp *mtp, queue_t *q, mblk_t *msg, int err){	mblk_t *mp;	if ((mp = mi_allocb(q, 2, BPRI_MED))) {		DB_TYPE(mp) = M_ERROR;		*mp->b_wptr++ = err < 0 ? -err : err;		*mp->b_wptr++ = err < 0 ? -err : err;		mtp_set_state(mtp, TS_NOSTATES);		freemsg(msg);		mi_strlog(mtp->rq, STRLOGRX, SL_TRACE, "<- M_ERROR");		putnext(mtp->rq, mp);		return (0);	}	return (-ENOBUFS);}/** * t_conn_ind: - issue a T_CONN_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @src: souce address * @opt: options * @dp: user data */static inline fastcall __unlikely intt_conn_ind(struct mtp *mtp, queue_t *q, mblk_t *bp,	   t_scalar_t seq, struct mtp_addr *src, struct mtp_opts *opt, mblk_t *dp){	struct T_conn_ind *p;	mblk_t *mp;	size_t src_len = t_addr_size(src);	size_t opt_len = t_opts_size(opt);	size_t msg_len = sizeof(*p) + src_len + opt_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->rq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = T_CONN_IND;			p->SRC_length = src_len;			p->SRC_offset = sizeof(*p);			p->OPT_length = opt_len;			p->OPT_offset = sizeof(*p) + src_len;			p->SEQ_number = seq;			mp->b_wptr += sizeof(*p);			t_build_addr(src, mp->b_wptr);			mp->b_wptr += src_len;			t_build_opts(opt, mp->b_wptr);			mp->b_wptr += opt_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_CONN_IND");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * t_conn_con: - issue a T_CONN_CON primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @res: responding address * @opt: options * @dp: user data */static inline fastcall __unlikely intt_conn_con(struct mtp *mtp, queue_t *q, mblk_t *bp,	   struct mtp_addr *res, struct mtp_opts *opt, mblk_t *dp){	struct T_conn_con *p;	mblk_t *mp;	size_t res_len = t_addr_size(res);	size_t opt_len = t_opts_size(opt);	size_t msg_len = sizeof(*p) + res_len + opt_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->rq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = T_CONN_CON;			p->RES_length = res_len;			p->RES_offset = sizeof(*p);			p->OPT_length = opt_len;			p->OPT_offset = sizeof(*p) + opt_len;			mp->b_wptr += sizeof(*p);			t_build_addr(res, mp->b_wptr);			mp->b_wptr += res_len;			t_build_opts(opt, mp->b_wptr);			mp->b_wptr += opt_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_CONN_CON");			if (mtp_get_state(mtp) != TS_WCON_CREQ)				swerr();			mtp_set_state(mtp, TS_DATA_XFER);			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * t_discon_ind: - issue a T_DISCON_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @reason: reason for disconnection * @dp: user data */static inline fastcall __unlikely intt_discon_ind(struct mtp *mtp, queue_t *q, mblk_t *bp, t_scalar_t reason, mblk_t *dp){	struct T_discon_ind *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (mtp_chk_state(mtp, (TSF_WCON_CREQ | TSF_WRES_CIND | TSF_DATA_XFER | TSF_WIND_ORDREL | TSF_WREQ_ORDREL))) {		if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = T_DISCON_IND;				p->DISCON_reason = reason;				p->SEQ_number = 0;				mp->b_wptr += sizeof(*p);				mtp_set_state(mtp, TS_IDLE);				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_DISCON_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freeb(bp);	freemsg(dp);	return (0);}/** * t_data_ind: - issue a T_DATA_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @more: more data flag * @dp: user data */static inline fastcall __unlikely intt_data_ind(struct mtp *mtp, queue_t *q, mblk_t *bp, t_scalar_t more, mblk_t *dp){	struct T_data_ind *p;	mblk_t *mp;	if (mtp_chk_state(mtp, (TSF_DATA_XFER | TSF_WIND_ORDREL))) {		if (likely((mp = mi_allocb(q, sizeof(*p), BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = T_DATA_IND;				p->MORE_flag = more;				mp->b_wptr += sizeof(*p);				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_DATA_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freemsg(mp);	return (0);}/** * t_exdata_ind: - issue a T_EXDATA_IND primitive upstream * @mtp: private structure * @q: active queue * @bp: message block to free upon success * @more: more data flag * @dp: user data */static inline fastcall __unlikely intt_exdata_ind(struct mtp *mtp, queue_t *q, mblk_t *bp, t_scalar_t more, mblk_t *dp){	struct T_exdata_ind *p;	mblk_t *mp;	if (mtp_chk_state(mtp, (TSF_DATA_XFER | TSF_WIND_ORDREL))) {		if (likely((mp = mi_allocb(q, sizeof(*p), BPRI_MED)) != NULL)) {			if (likely(canputnext(mtp->rq))) {				DB_TYPE(mp) = M_PROTO;				mp->b_band = 1;				p = (typeof(p)) mp->b_wptr;				p->PRIM_type = T_EXDATA_IND;				p->MORE_flag = more;				mp->b_wptr += sizeof(*p);				mp->b_cont = dp;				if (bp)					freeb(bp);				mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_EXDATA_IND");				putnext(mtp->rq, mp);				return (0);			}			freeb(mp);			return (-EBUSY);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freemsg(mp);	return (0);}/** * t_info_ack: - issue a T_INFO_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intt_info_ack(struct mtp *mtp, queue_t *q, mblk_t *msg){	struct T_info_ack *p;	mblk_t *mp;	if (likely((mp = mi_allocb(q, sizeof(*p), BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		mp->b_wptr += sizeof(*p);		*p = mtp->prot;		freemsg(msg);		mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_INFO_ACK");		putnext(mtp->rq, mp);		return (0);	}	return (-ENOBUFS);}/* * t_bind_ack: - issue a T_BIND_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @add: bound address * @cons: negotiated number of oustanding connection indications */static inline fastcall __unlikely intt_bind_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, struct mtp_addr *add, t_scalar_t cons){	struct T_bind_ack *p;	mblk_t *mp;	size_t add_len = t_addr_size(add);	size_t msg_len = sizeof(*p) + add_len;	if (mtp_get_state(mtp) == TS_WACK_BREQ) {		if (unlikely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {			DB_TYPE(mp) = M_PCPROTO;			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = T_BIND_ACK;			p->ADDR_length = add_len;			p->ADDR_offset = sizeof(*p);			p->CONIND_number = cons;			mp->b_wptr += sizeof(*p);			t_build_addr(add, mp->b_wptr);			mp->b_wptr += add_len;			mtp_bind(mtp, add);			mtp_set_state(mtp, TS_IDLE);			freemsg(msg);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_BIND_ACK");			putnext(mtp->rq, mp);			return (0);		}		return (-ENOBUFS);	}	mi_strlog(q, 0, SL_ERROR, "unexpected indication for state %u", mtp_get_state(mtp));	freemsg(msg);	return (0);}/* * t_error_ack: - issue a T_ERROR_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @prim: primitive in error * @etypr: error type */static inline fastcall __unlikely intt_error_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, const t_scalar_t prim, t_scalar_t etype){	struct T_error_ack *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		p->PRIM_type = T_ERROR_ACK;		p->ERROR_prim = prim;		p->TLI_error = etype < 0 ? TSYSERR : etype;		p->UNIX_error = etype < 0 ? -etype : 0;		mp->b_wptr += sizeof(*p);		switch (mtp_get_state(mtp)) {#ifdef TS_WACK_OPTREQ		case TS_WACK_OPTREQ:#endif		case TS_WACK_UREQ:		case TS_WACK_CREQ:			mtp_set_state(mtp, TS_IDLE);			break;		case TS_WACK_BREQ:			mtp_set_state(mtp, TS_UNBND);			break;		case TS_WACK_CRES:			mtp_set_state(mtp, TS_WRES_CIND);			break;		case TS_WACK_DREQ6:			mtp_set_state(mtp, TS_WCON_CREQ);			break;		case TS_WACK_DREQ7:			mtp_set_state(mtp, TS_WRES_CIND);			break;		case TS_WACK_DREQ9:			mtp_set_state(mtp, TS_DATA_XFER);			break;		case TS_WACK_DREQ10:			mtp_set_state(mtp, TS_WIND_ORDREL);			break;		case TS_WACK_DREQ11:			mtp_set_state(mtp, TS_WREQ_ORDREL);			break;		default:			/* Note: if we are not in a WACK state we simply do not change state.  This 			   occurs normally when we send TOUTSTATE or TNOTSUPPORT or are responding			   to a T_OPTMGMT_REQ in other than TS_IDLE state. */			break;		}		freemsg(msg);		mi_strlog(q, STRLOGRX, SL_TRACE, "<- T_ERROR_ACK");		putnext(mtp->rq, mp);		return (0);	}	return (-ENOBUFS);}/** * t_ok_ack: - issue a T_OK_ACK primitive upstream * @mtp: private structure * @q: active queue * @msg: message to free upon success * @prim: correct primitive * @seq: sequence number * @tok: stream token */static inline fastcall __unlikely intt_ok_ack(struct mtp *mtp, queue_t *q, mblk_t *msg, t_scalar_t prim, t_scalar_t seq, t_scalar_t tok){	struct T_ok_ack *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		p->PRIM_type = T_OK_ACK;		p->CORRECT_prim = prim;		mp->b_wptr += sizeof(*p);		switch (mtp_get_state(mtp)) {		case TS_WACK_CREQ:			mtp_connect(mtp, &mtp->dst);			mtp_set_state(mtp, TS_WCON_CREQ);			break;		case TS_WACK_UREQ:			mtp_unbind(mtp);			mtp_set_state(mtp, TS_UNBND);			break;		case TS_WACK_OPTREQ:			mtp_set_state(mtp, TS_IDLE);			break;		case TS_WACK_CRES:			/* FIXME: need to use sequence and token */			mtp_set_state(mtp, TS_DATA_XFER);			break;		case TS_WACK_DREQ6:

⌨️ 快捷键说明

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