📄 m2pa.c
字号:
p->sl_primitive = SL_BSNT_IND; p->sl_bsnt = bsnt; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_IN_SERVICE_IND * * Builds an in service indication. */static inline mblk_t *sl_in_service_ind(void){ mblk_t *mp; sl_in_service_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p->sl_primitive = SL_IN_SERVICE_IND; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_OUT_OF_SERVICE_IND * * Builds an out of service indication given the reason for link failure. */static inline mblk_t *sl_out_of_service_ind(int reason){ mblk_t *mp; sl_out_of_service_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PCPROTO; p->sl_primitive = SL_OUT_OF_SERVICE_IND; p->sl_timestamp = jiffies; p->sl_reason = reason; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_REMOTE_PROCESSOR_OUTAGE_IND * * Builds a remote processor outage indication. */static inline mblk_t *sl_remote_processor_outage_ind(void){ mblk_t *mp; sl_rem_proc_out_ind_t *p; if ( (mp = allocb(sizoef(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PCPROTO; p->sl_primitive = SL_REMOTE_PROCESSOR_OUTAGE_IND; p->sl_timestamp = jiffies; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_REMOTE_PROCESSOR_RECOVERED_IND * * Builds a remote processor recovered indication. */static inline mblk_t *sl_remote_processor_recovered_ind(void){ mblk_t *mp; sl_rem_proc_recovered_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PCPROTO; p->sl_primitive = SL_REMOTE_PROCESSOR_RECOVERED_IND; p->sl_timestamp = jiffies; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_RTB_CLEARED_IND * * Builds a retransmit buffer cleared indication. */static inline mblk_t *sl_rtb_cleared_ind(void){ mblk_t *mp; sl_rtb_cleared_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p->sl_primitive = SL_RTB_CLEARED_IND; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_RETRIEVAL_NOT_POSSIBLE_IND * * bUilds a retrieval not possible indication. */static inline mblk_t *sl_retieval_not_possible_ind(void){ mblk_t *mp; sl_retrieval_not_poss_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p->sl_primitive = SL_RETRIEVAL_NOT_POSSIBLE_IND; mp->b_wptr += sizeof(*p); } return(mp);}/* * SL_BSNT_NOT_RETRIEVABLE_IND * * Builds a BSNT not retrievable indication given the best value of the BSNT * which could be used. (Why the BSNT?) */static inline mblk_t *sl_bsnt_not_retrievable_ind(int bsnt){ mblk_t *mp; sl_bsnt_not_retr_ind_t *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p->sl_primitive = SL_BSNT_NOT_RETRIEVABLE_IND; p->bsnt = bsnt; mp->b_wptr += sizeof(*p); } return(mp);}/* * ========================================================================= * * M2PA-Provider --> T-Provider (SCTP) Primitives (M_CTL, M_PROTO, M_PCPROTO) * * ========================================================================= *//* * T_INFO_REQ * * We might use this primitive if the T-Provider is not SCTP to check the * capabilities of the T-Provider before exchanging any other primitives. */static inline mblk_t *t_info_req(void){ mblk_t *mp; struct T_info_req *p; if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) { mp->b_datap->db_type = M_PCPROTO; p = (struct T_info_req *)mp->b_wptr; p->PRIM_type = T_INFO_REQ; mp->b_wptr += sizeof(*p); } return(mp);}/* * T_BIND_REQ * * This is used by M2PA to bind the T-Provider to a local transport address * before attempting to connect the T-Provider. This builds the bind request * primitive given a point and length of the address and the number of * outstanding connection indications which is required. */static inline mblk_t *t_bind_req(caddr_t add_ptr, size_t add_len, int cons){ mblk_t *mp; struct T_bind_req *p; if ( (mp = allocb(sizeof(*p)+add_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PCPROTO; p = (struct T_bind_req *)mp->b_wptr; p->PRIM_type = T_BIND_REQ; p->ADDR_length = add_len; p->ADDR_offset = sizeof(*p); p->CONIND_number = cons; mp->b_wptr += sizeof(*p); bcopy(add_ptr, mp->b_wptr, add_len); mp->b_wptr += add_len; } return(mp);}/* * T_OPTMGMT_REQ * * This might be used by M2PA to set some local and associative options * before establishing a connection. */static inline mblk_t *t_optmgmt_req(caddr_t opt_ptr, size_t opt_len, int flags){ mblk_t *mp; struct T_optmgmt_req *p; if ( (mp = allocb(sizeof(*p)+opt_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PCPROTO; p = (struct T_optmgmt_req *)mp->b_wptr; p->PRIM_type = T_OPTMGMT_REQ; p->OPT_length = opt_len; p->OPT_offset = sizeof(*p); p->MGMT_flags = flags; mp->b_wptr += sizeof(*p); bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; } return(mp);}/* * T_ADDR_REQ * * This is really not necessary, but it is here anyways. Particularly if * there is a non-SCTP T-Providder which does not provide the address * information in a usable (or storable) format in the appropriate * primitives. This should be unnecessary for the OpenSS7 SCTP T-Provider. */static inline mblk_t *t_addr_req(void){ mblk_t *mp; struct T_addr_req *p; if ( (mp = allocb(sizeof(*p), BPRI_MED)) ) { mp->b_datap->db_type = M_PCPROTO; p = (struct T_addr_req *)mp->b_wptr; p->PRIM_TYPE = T_ADDR_REQ; mp->b_wptr += sizeof(*p); } return(mp);}/* * T_CONN_REQ * * This is used to actively request a connection to the transport peer. * * Builds a transport connection request given the destination address and * the options associated with the connection. */static inline mblk_t *t_conn_req(caddr_t dst_ptr, size_t dst_len, caddr_t opt_ptr, size_t opt_len){ mblk_t *mp; struct T_conn_req *p; if ( (mp = allocb(sizeof(*p)+dst_len+opt_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_conn_req *)mp->b_wptr; p->PRIM_TYPE = T_CONN_REQ; p->DEST_length = dst_len; p->DEST_offset = dst_len?sizeof(*p):0; p->OPT_length = opt_len; p->OPT_offset = opt_len?sizeof(*p)+dst_len:0; mp->b_wptr += sizeof(*p); bcopy(dst_ptr, mp->b_wptr, dst_len); mp->b_wptr += dst_len; bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; } return(mp);}/* * T_CONN_RES * * This is used to accept a passive connection from the transport peer. We * use XTI/TLI semantics here an always accept the connection on the same * stream which was listening. Remember that SCTP can provide a T_CONN_IND * while in the T_DATAXFER state (for SCTP Restart) which must also be * accepted on this stream. */static inline mblk_t *t_conn_res(queue_t *q, caddr_t opt_ptr, size_t opt_len, int seq, mblk_t *dp){ mblk_t *mp; struct T_conn_res *p; if ( (mp = allocb(sizeof(*p)+opt_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_conn_res *)mp->b_wptr; p->PRIM_type = T_CONN_RES; p->QUEUE_ptr = q; p->OPT_length = opt_len; p->OPT_offset = opt_len?sizeof(*p):0; p->SEQ_number = seq; mp->b_wptr += sizeof(*p); bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; mp->b_cont = dp; } return(mp);}/* * T_DATA_REQ * * This is used to send normal (ordered) messages on the control or default * SCTP-stream (stream 0). * */static inline mblk_t *t_data_req(mblk_t *dp){ mblk_t *mp; struct T_data_req *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_data_req *)mp->b_wptr; p->PRIM_type = T_DATA_REQ; p->MORE_flag = 0; mp->b_wptr += sizeof(*p); mp->b_cont = dp; } return(mp);}/* * T_EXDATA_REQ * * This is used to send expedited (really, unordered) messages on the control * or default SCTP-stream (stream 0). */static inline mblk_t *t_exdata_req(mblk_t *dp){ mblk_t *mp; struct T_exdata_req *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; mp->b_band = 1; p = (struct T_exdata_req *)mp->b_wptr; p->PRIM_type = T_EXDATA_REQ; p->MORE_flag = 0; mp->b_wptr += sizeof(*p); mp->b_cont = dp; } return(mp);}/* * T_OPTDATA_REQ * * This is used to send normal (ordered) or expedited (unordered) data on a * specific stream. This builds a T_OPTDATA_REQ given the data flags, * options pointer and length, and the M_DATA blocks to include in the * message. */static inline mblk_t *t_optdata_req(int flags, caddr_t opt_ptr, size_t opt_len, mblk_t *dp){ mblk_t *mp; struct T_optdata_req *p; if ( (mp = allocb(sizeof(*p)+opt_len, BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; mp->b_band = (flags & M2PA_URGENT) ? 1 : 0; p = (struct T_optdata_req *)mp->b_wptr; p->PRIM_type = T_OPTDATA_REQ; p->DATA_flag = flags; p->OPT_length = opt_len; p->OPT_offset = opt_len?sizeof(*p):0; mp->b_wptr += sizeof(*p); bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; mp->b_cont = dp; } return(mp);}/* * T_DISCON_REQ * * This is used to ABORT the SCTP association under brutal circumstances. */static inline mblk_t *t_discon_req(int seq){ mblk_t *mp; struct T_discon_req *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_discon_req *)mp->b_wptr; p->PRIM_type = T_DISCON_REQ; p->SEQ_number = seq; mp->b_wptr += sizeof(*p); } return(mp);}/* * T_ORDREL_REQ * * This is used to peform a SHUTDOWN on the SCTP association. */static inline mblk_t *t_ordrel_req(void){ mblk_t *mp; struct T_ordrel_req *p; if ( (mp = allocb(sizeof(*p), BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_ordrel_req *)mp->b_wptr; p->PRIM_type = T_DISCON_REQ; mp->b_wptr += sizeof(*p); } return(mp);}/* * T_UNITDATA_REQ * * This is not normally used for a SCTP T-Provider (which is * connection- * oriented only). However, if we use a connectionless T-Provider we may use * these messages, so here it is. */static inline mblk_t *t_unitdata_req( caddr_t dst_ptr, size_t dst_len, caddr_t opt_ptr, size_t opt_len, mblk_t *dp){ mblk_t *mp; struct T_unitdata_req *p; if ( (mp = allocb(sizeof(*p)+dst_len+opt_len, BPRI_HI)) ) { mp->b_datap->db_type = M_PROTO; p = (struct T_unitdata_req *)mp->b_wptr; p->PRIM_type = T_DISCON_REQ; p->DEST_length = dst_len; p->DEST_offset = dst_len?sizeof(*p):0; p->OPT_length = opt_len; p->OPT_offset = opt_len?sizeof(*p)+dst_len:0; mp->b_wptr += sizeof(*p); bcopy(dst_ptr, mp->b_wptr, dst_len); mp->b_wptr += dst_len; bcopy(opt_ptr, mp->b_wptr, opt_len); mp->b_wptr += opt_len; } return(mp);}}/* * Mapping of states: * * M2PA State T-Provider State(s) * ------------------- -------------------------------------------- * M2PA_STATE_IDLE (uninitialized) * * M2PA_STATE_OOS TS_UNBND TS_WACK_UREQ TS_IDLE TS_WACK_OPREQ * TS_WACK_DREQ6 TS_WACK_DREQ7 TS_WACK_DREQ9 * TS_WACK_DREQ10 TS_WACK_DREQ11 TS_WIND_ORDREL * TS_WACK_CREQ TS_WACK_CRES * * M2PA_STATE_AIP TS_WACK_BREQ TS_IDLE TS_WCON_CREQ TS_WRES_CIND * TS_WACK_OPREQ TS_WACK_CREQ TS_WACK_CRES * * M2PA_STATE_INS_LOCAL TS_DATA_XFER * * M2PA_STATE_INS TS_DATA_XFER TS_WREQ_ORDREL * * M2PA_RETRIEVAL TS_WIND_ORDREL TS_WACK_DREQ6 TS_WACK_DREQ7 * TS_WACK_DREQ9 TS_WACK_DREQ10 TS_WACK_DREQ11 * TS_WACK_CREQ TS_WACK_CRES TS_IDLE TS_WACK_UREQ * TS_UNBND * ------------------- -------------------------------------------- *//* * ========================================================================= * * M2PA-Provider --> M2PA-Peer Primitives (Sent Messages) * * ========================================================================= *//* * M2PA SEND DATA * * TODO:- We should probably be doing several more things here. We should be * invoking an option to have data acknowledged to us when it is acknowledged * by the other end and have the SSN and TSN returned to us. Also we should * place a token on the data to permit correlating acknowledgements with the * outgoing data (use the mblk_t pointer). Also, we might want to dig into * the M_DATA blocks and pull out the SLS for the message so that we can * choose the stream id to send on based on the SLS. */static inline mblk_t *m2pa_send_data(mblk_t *dp){ mblk_t *mp; struct T_optdata_req *p; static struct sctp_opt_sid opt = { { T_INET_SCTP, T_SCTP_SID, sizeof(opt) }, 1 } }; return t_optdata_req( 0, (caddr_t)&opt, sizeof(opt), dp );}/* * M2PA SEND STATUS * * I have added sending M2PA_STATUS_OUT_OF_SERVICE here because I believe * that there is no reason for dropping the SCTP association is there is no * need to do so. */static inline mblk_t *m2pa_send_status(uint32_t status){ mblk_t *mp; if ( (mp = allocb(sizeof(uint32_t), BPRI_HI)) ) { mp->b_datap->db_type = M_DATA; mp->b_band = M2PA_HI_PRIORITY; *((uint32_t *)mp->b_wptr)++ = status; } return(mp);}static inline mblk_t *m2pa_send_in_service(void) { return m2pa_send_status(M2PA_STATUS_IN_SERVICE);}static inline mblk_t *m2pa_send_sipo(void) { return m2pa_send_status(M2PA_STATUS_PROCESSOR_OUTAGE);}static inline mblk_t *m2pa_send_not_sipo(void) { return m2pa_send_status(M2PA_STATUS_PROCESSOR_ENDED);}static inline mblk_t *m2pa_send_sib(void) { return m2pa_send_status(M2PA_STATUS_STATUS_BUSY);}static inline mblk_t *m2pa_send_not_sib(void) { return m2pa_send_status(M2PA_STATUS_STATUS_BUSY_ENDED);}static inline mblk_t *m2pa_send_sios(void) { return m2pa_send_status(M2PA_STATUS_OUT_OF_SERVICE);}static inline mblk_t *m2pa_send_sio(void) { return m2pa_send_status(M2PA_STATUS_ALIGN);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -