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

📄 mtp_npi.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 5 页
字号:
			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * t_uderror_ind: - issue a T_UDERROR_IND primitive * @mtp: MTP private data * @q: active queue * @bp: message block to free upon success * @dst: destination address (or NULL) * @opt: options (or NULL) * @dp: user data * @etype: error type */static inline fastcall __unlikely intn_uderror_ind(struct mtp *mtp, queue_t *q, mblk_t *bp,	      struct mtp_addr *dst, mblk_t *dp, mtp_ulong etype){	N_uderror_ind_t *p;	mblk_t *mp;	size_t dst_len = n_addr_size(dst);	size_t msg_len = sizeof(*p) + dst_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(bcanputnext(mtp->rq, 2))) {			DB_TYPE(mp) = M_PROTO;			mp->b_band = 2;	/* XXX move ahead of data indications */			p = (typeof(p)) mp->b_wptr;			p->PRIM_type = N_UDERROR_IND;			p->DEST_length = dst_len;			p->DEST_offset = dst_len ? sizeof(*p) : 0;			p->ERROR_type = etype;			mp->b_wptr += sizeof(*p);			n_build_addr(dst, mp->b_wptr);			mp->b_wptr += dst_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_UDERROR_IND");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * n_datack_ind: - issue a N_DATACK_IND primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intn_datack_ind(struct mtp *mtp, queue_t *q, mblk_t *msg){	N_datack_ind_t *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	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 = N_DATACK_IND;			mp->b_wptr += sizeof(*p);			freemsg(msg);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_DATACK_IND");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * n_reset_ind: - issue a N_RESET_IND primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success * @orig: origin of reset * @reason: reason for reset */static inline fastcall __unlikely intn_reset_ind(struct mtp *mtp, queue_t *q, mblk_t *msg, np_ulong orig, np_ulong reason){	N_reset_ind_t *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	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 = N_RESET_IND;			p->RESET_orig = orig;			p->RESET_reason = reason;			mp->b_wptr += sizeof(*p);			freemsg(msg);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_RESET_IND");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * n_reset_con: - issue a N_RESET_CON primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intn_reset_con(struct mtp *mtp, queue_t *q, mblk_t *msg){	N_reset_con_t *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	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 = N_RESET_CON;			mp->b_wptr += sizeof(*p);			freemsg(msg);			mi_strlog(q, STRLOGRX, SL_TRACE, "<- N_RESET_CON");			putnext(mtp->rq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/* *  ------------------------------------------------------------------------- * *  Primitives sent downstream. * *  ------------------------------------------------------------------------- *//** * mtp_bind_req: - issue a MTP_BIND_REQ primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success * @add: address to which to bind (or NULL) * @flags: bind flags */static inline fastcall __unlikely intmtp_bind_req(struct mtp *mtp, queue_t *q, mblk_t *msg, struct mtp_addr *add, mtp_ulong flags){	struct MTP_bind_req *p;	mblk_t *mp;	size_t add_len = add ? sizeof(*add) : 0;	size_t msg_len = sizeof(*p) + add_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		DB_TYPE(mp) = M_PCPROTO;		p = (typeof(p)) mp->b_wptr;		p->mtp_primitive = MTP_BIND_REQ;		p->mtp_addr_length = add_len;		p->mtp_addr_offset = sizeof(*p);		p->mtp_bind_flags = flags;		mp->b_wptr += sizeof(*p);		bcopy(add, mp->b_wptr, add_len);		mp->b_wptr += add_len;		freemsg(msg);		mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_BIND_REQ ->");		putnext(mtp->wq, mp);		return (0);	}	return (-ENOBUFS);}/** * mtp_unbind_req: - issue a MTP_UNBIND_REQ primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intmtp_unbind_req(struct mtp *mtp, queue_t *q, mblk_t *msg){	struct MTP_unbind_req *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->mtp_primitive = MTP_UNBIND_REQ;		mp->b_wptr += sizeof(*p);		freemsg(msg);		mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_UNBIND_REQ ->");		putnext(mtp->wq, mp);		return (0);	}	return (-ENOBUFS);}/** * mtp_conn_req: - issue a MTP_CONN_REQ primitive * @mtp: MTP private data * @q: active queue * @bp: message block to free upon success * @add: address to which to connect (or NULL) * @flags: connect flags * @dp: user data */static inline fastcall __unlikely intmtp_conn_req(struct mtp *mtp, queue_t *q, mblk_t *bp,	     struct mtp_addr *add, mtp_ulong flags, mblk_t *dp){	struct MTP_conn_req *p;	mblk_t *mp;	size_t add_len = add ? sizeof(*add) : 0;	size_t msg_len = sizeof(*p) + add_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->wq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->mtp_primitive = MTP_CONN_REQ;			p->mtp_addr_length = add_len;			p->mtp_addr_offset = add_len ? sizeof(*p) : 0;			p->mtp_conn_flags = flags;			mp->b_wptr += sizeof(*p);			bcopy(add, mp->b_wptr, add_len);			mp->b_wptr += add_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_CONN_REQ ->");			putnext(mtp->wq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * mtp_discon_req: - issue an MTP_DISCON_REQ primitive * @mtp: MTP private data * @q: active queue * @bp: message block to free upon success * @dp: user data */static inline fastcall __unlikely intmtp_discon_req(struct mtp *mtp, queue_t *q, mblk_t *bp, mblk_t *dp){	struct MTP_discon_req *p;	mblk_t *mp;	size_t msg_len = sizeof(*p);	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->wq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->mtp_primitive = MTP_DISCON_REQ;			mp->b_wptr += sizeof(*p);			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_DISCON_REQ ->");			putnext(mtp->wq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * mtp_addr_request: - issue an MTP_ADDR_REQ primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intmtp_addr_req(struct mtp *mtp, queue_t *q, mblk_t *msg){	struct MTP_addr_req *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->mtp_primitive = MTP_ADDR_REQ;		mp->b_wptr += sizeof(*p);		freemsg(msg);		mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_ADDR_REQ ->");		putnext(mtp->wq, mp);		return (0);	}	return (-ENOBUFS);}/** * mtp_info_req: - issue an MTP_INFO_REQ primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success */static inline fastcall __unlikely intmtp_info_req(struct mtp *mtp, queue_t *q, mblk_t *msg){	struct MTP_info_req *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->mtp_primitive = MTP_INFO_REQ;		mp->b_wptr += sizeof(*p);		freemsg(msg);		mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_INFO_REQ ->");		putnext(mtp->wq, mp);		return (0);	}	return (-ENOBUFS);}/** * mtp_optmgmt_req: - issue an MTP_OPTMGMT_REQ primitive * @mtp: MTP private data * @q: active queue * @msg: message to free upon success * @opt: options (or NULL) * @flags: management flags */static inline fastcall __unlikely intmtp_optmgmt_req(struct mtp *mtp, queue_t *q, mblk_t *msg, union N_qos_mtp *opt, mtp_ulong flags){	struct MTP_optmgmt_req *p;	mblk_t *mp;	struct t_opthdr *oh;	size_t opt_len = opt ? 2 * sizeof(*oh) + 2 * sizeof(t_scalar_t) : 0;	size_t msg_len = sizeof(*p) + opt_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(canputnext(mtp->wq))) {			DB_TYPE(mp) = M_PROTO;			p = (typeof(p)) mp->b_wptr;			p->mtp_primitive = MTP_OPTMGMT_REQ;			p->mtp_opt_length = opt_len;			p->mtp_opt_offset = sizeof(*p);			p->mtp_mgmt_flags = flags;			mp->b_wptr += sizeof(*p);			if (opt_len) {				oh = (typeof(oh)) mp->b_wptr;				oh->level = T_SS7_MTP;				oh->name = T_MTP_SLS;				oh->len = sizeof(*oh) + sizeof(t_scalar_t);				oh->status = T_SUCCESS;				mp->b_wptr += sizeof(*oh);				*(t_scalar_t *)mp->b_wptr = opt->n_qos_info.sls;				mp->b_wptr += sizeof(t_scalar_t);				oh = (typeof(oh)) mp->b_wptr;				oh->level = T_SS7_MTP;				oh->name = T_MTP_MP;				oh->len = sizeof(*oh) + sizeof(t_scalar_t);				oh->status = T_SUCCESS;				mp->b_wptr += sizeof(*oh);				*(t_scalar_t *)mp->b_wptr = opt->n_qos_info.mp;				mp->b_wptr += sizeof(t_scalar_t);			}			freemsg(msg);			mi_strlog(q, STRLOGTX, SL_TRACE, "MTP_OPTMGMT_REQ ->");			putnext(mtp->wq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/** * mtp_transfer_req: - issue an MTP_TRANSFER_REQ primitive * @mtp: MTP private data * @q: active queue * @bp: message block to free upon success * @dst: destination address (or NULL) * @pri: message priority * @sls: signalling link selection * @dp: user data */static inline fastcall __unlikely intmtp_transfer_req(struct mtp *mtp, queue_t *q, mblk_t *bp,		 struct mtp_addr *dst, mtp_ulong pri, mtp_ulong sls, mblk_t *dp){	struct MTP_transfer_req *p;	mblk_t *mp;	size_t dst_len = dst ? sizeof(*dst) : 0;	size_t msg_len = sizeof(*p) + dst_len;	if (likely((mp = mi_allocb(q, msg_len, BPRI_MED)) != NULL)) {		if (likely(bcanputnext(mtp->wq, dp->b_band))) {			DB_TYPE(mp) = M_PROTO;			mp->b_band = dp->b_band;			p = (typeof(p)) mp->b_wptr;			p->mtp_primitive = MTP_TRANSFER_REQ;			p->mtp_dest_length = dst_len;			p->mtp_dest_offset = dst_len ? sizeof(*p) : 0;			p->mtp_mp = pri;			p->mtp_sls = sls;			mp->b_wptr += sizeof(*p);			bcopy(dst, mp->b_wptr, dst_len);			mp->b_wptr += dst_len;			mp->b_cont = dp;			if (bp)				freeb(bp);			mi_strlog(q, STRLOGDA, SL_TRACE, "MTP_TRANSFER_REQ ->");			putnext(mtp->wq, mp);			return (0);		}		freeb(mp);		return (-EBUSY);	}	return (-ENOBUFS);}/* *  ------------------------------------------------------------------------- * *  Primitives received from above. * *  ------------------------------------------------------------------------- *//** * n_data: - process M_DATA message * @mtp: private structure * @q: active queue * @mp: the message * * To support pseudo-connectionless modes, when this message is sent for N_CLNS we should send the * data to the same adress and with the same options as the last N_UNITDATA_REQ primitive. */static inline fastcall __hot_read intn_data(struct mtp *mtp, queue_t *q, mblk_t *mp){	const size_t dlen = msgdsize(mp);	if (mtp->prot.SERV_type == N_CLNS)		goto notsupport;	if (mtp_chk_state(mtp, (NSF_IDLE | NSF_WRES_RIND)))		goto discard;	if (mtp_get_state(mtp) != NS_DATA_XFER)		goto outstate;	if (dlen == 0 || dlen > mtp->prot.NSDU_size || dlen > mtp->prot.NIDU_size)		goto baddata;	return mtp_transfer_req(mtp, q, mp, &mtp->dst, mtp->options.mp, mtp->options.sls, mp);      baddata:	mi_strlog(q, 0, SL_TRACE, "bad data size %lu", (ulong)dlen);	goto error;      outstate:	mi_strlog(q, 0, SL_TRACE, "would place i/f out of state");	goto error;      discard:	mi_strlog(q, 0, SL_TRACE, "ignore in idle state");	freemsg(mp);	return (0);      notsupport:	mi_strlog(q, 0, SL_TRACE, "primitive not supported for N_CLNS");	goto error;      error:	return m_error(mtp, q, mp, EPROTO);}/** * n_conn_req: - process N_CONN_REQ primitive * @mtp: private structure * @q: active queue * @mp: the message * * As MTP is really a connectionless protocol, when we form a connection we simply remember the * destination address.  Some interim MTPs had the abilitty to send a UPT (User Part Test) message. * If the protocol variant has this ability, we wait for the result of the User Part Test before * confirming the connection.

⌨️ 快捷键说明

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