?? mtp_tpi.c
字號:
{ 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 + -