📄 m2pa_sdl.c
字号:
#endif/* * ========================================================================= * * NPI User (M2PA) -> NPI Provider (SCTP) Primitives * * ========================================================================= *//* * N_DATA_REQ * --------------------------------------------- */static intn_data_req(m2pa_t *m2, ulong flags, void *qos_ptr, size_t qos_len, mblk_t *dp){ mblk_t *mp; N_data_req_t *p; if ( canputnext(m2->wq) ) { if ( (mp = allocb(sizeof(*p)+qos_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PROTO; p = ((N_data_req_t *)mp->b_wptr)++; p->PRIM_type = N_DATA_REQ; p->DATA_xfer_flags = flags; bcopy(qos_ptr, mp->b_wptr, qos_len); mp->b_wptr += qos_len; mp->b_cont = dp; putnext(m2->wq, mp); return(0); } rare(); return(-ENOBUFS); } seldom(); return(-EBUSY);}/* * N_EXDATA_REQ * --------------------------------------------- */static intn_exdata_req(m2pa_t *m2, void *qos_ptr, size_t qos_len, mblk_t *dp){ mblk_t *mp; N_exdata_req_t *p; if ( bcanputnext(m2->wq, 1) ) { if ( (mp = allocb(sizeof(*p)+qos_len, BPRI_MED)) ) { mp->b_datap->db_type = M_PROTO; p = ((N_exdata_req_t *)mp->b_wptr)++; p->PRIM_type = N_EXDATA_REQ; bcopy(qos_ptr, mp->b_wptr, qos_len); mp->b_wptr += qos_len; mp->b_cont = dp; putnext(m2->wq, mp); return(0); } rare(); return(-ENOBUFS); } seldom(); return(-EBUSY);}/* * ========================================================================= * * M2PA PDU Message Functions * * ========================================================================= */#define M2PA_PPI 5#define M2PA_MESSAGE_CLASS 11#define M2PA_VERSION 1#define M2PA_MTYPE_DATA 1#define M2PA_MTYPE_STATUS 2#define M2PA_MTYPE_PROVING 3#define M2PA_MTYPE_DATACK 4#define M2PA_DATA_MESSAGE \ __constant_htonl((M2PA_VERSION<<24)|(M2PA_MESSAGE_CLASS<<8)|M2PA_MTYPE_DATA)#define M2PA_STATUS_MESSAGE \ __constant_htonl((M2PA_VERSION<<24)|(M2PA_MESSAGE_CLASS<<8)|M2PA_MTYPE_STATUS)#define M2PA_PROVING_MESSAGE \ __constant_htonl((M2PA_VERSION<<24)|(M2PA_MESSAGE_CLASS<<8)|M2PA_MTYPE_PROVING)#define M2PA_DATACK_MESSAGE \ __constant_htonl((M2PA_VERSION<<24)|(M2PA_MESSAGE_CLASS<<8)|M2PA_MTYPE_DATACK)#define M2PA_STATUS_STREAM 0#define M2PA_DATA_STREAM 1#if 0/* * M2PA SEND PROVING * --------------------------------------------- */static intm2pa_send_proving(m2pa_t *m2, size_t plen){ int err; mblk_t *mp; N_qos_sel_data_sctp_t qos = { N_QOS_SEL_DATA_SCTP, M2PA_PPI, M2PA_DATA_STREAM, }; if ( (mp = allocb(2*sizeof(uint32_t)+plen, BPRI_MED)) ) { mp->b_datap->db_type = M_DATA; *((uint32_t *)mp->b_wptr)++ = M2PA_PROVING_MESSAGE; *((uint32_t *)mp->b_wptr)++ = __constant_htonl(2*sizeof(uint32_t)+plen); fixme(("We should include a test pattern.\n")); bzero(mp->b_wptr, plen); mp->b_wptr += plen; if ( !(err = n_data_req(m2, 0, &qos, sizeof(qos), mp)) ) return(0); freeb(mp); return(err); } return(-ENOBUFS);}#endif#define M2PA_STATUS_OUT_OF_SERVICE (__constant_htonl(0)) /* XXX */#define M2PA_STATUS_ALIGNMENT (__constant_htonl(1))#define M2PA_STATUS_PROVING_NORMAL (__constant_htonl(2))#define M2PA_STATUS_PROVING_EMERGENCY (__constant_htonl(3))#define M2PA_STATUS_IN_SERVICE (__constant_htonl(4))#define M2PA_STATUS_PROCESSOR_OUTAGE (__constant_htonl(5))#define M2PA_STATUS_PROCESSOR_ENDED (__constant_htonl(6))#define M2PA_STATUS_BUSY (__constant_htonl(7))#define M2PA_STATUS_BUSY_ENDED (__constant_htonl(8))/* * M2PA SEND STATUS * --------------------------------------------- */static intm2pa_send_status(m2pa_t *m2, uint32_t status){ int err; mblk_t *mp; N_qos_sel_data_sctp_t qos = { N_QOS_SEL_DATA_SCTP, M2PA_PPI, M2PA_STATUS_STREAM, };#if 0 { const char *r; switch ( status ) { case M2PA_STATUS_OUT_OF_SERVICE: r = "OUT_OF_SERVICE"; break; case M2PA_STATUS_ALIGNMENT: r = "ALIGNMENT"; break; case M2PA_STATUS_PROVING_NORMAL: r = "PROVING_NORMAL"; break; case M2PA_STATUS_PROVING_EMERGENCY: r = "PROVING_EMERGENCY"; break; case M2PA_STATUS_IN_SERVICE: r = "IN_SERVICE"; break; case M2PA_STATUS_PROCESSOR_OUTAGE: r = "PROCESSOR_OUTAGE"; break; case M2PA_STATUS_PROCESSOR_ENDED: r = "PROCESSOR_ENDED"; break; case M2PA_STATUS_BUSY: r = "BUSY"; break; case M2PA_STATUS_BUSY_ENDED: r = "BUSY_ENDED"; break; default: r = "(unknown)"; break; } ptrace(("%x, sending STATUS status = %s\n",(uint)m2,r)); }#endif if ( (mp = allocb(3*sizeof(uint32_t), BPRI_MED)) ) { mp->b_datap->db_type = M_DATA; *((uint32_t *)mp->b_wptr)++ = M2PA_STATUS_MESSAGE; *((uint32_t *)mp->b_wptr)++ = __constant_htonl(3*sizeof(uint32_t)); *((uint32_t *)mp->b_wptr)++ = status; if ( !(err = n_data_req(m2, 0, &qos, sizeof(qos), mp)) ) return(0); assert(mp->b_datap->db_ref); freeb(mp); return(err); } return(-ENOBUFS);}static voidm2pa_tx_sib_timeout(caddr_t data){ m2pa_t *m2 = (m2pa_t *)data; if ( !m2->timer_tx_sib ) return; else m2->timer_tx_sib = 0; if ( !(m2->flags & M2PA_FLAG_TX_BUSY) ) return; putctl1(m2->rq, M_CTL, M2PA_EVENT_TX_SIB_TIMEOUT); return;}/* * M2PA SEND DATA * --------------------------------------------- */static intm2pa_send_datack(m2pa_t *m2, ulong count){ int err; mblk_t *mp; N_qos_sel_data_sctp_t qos = { N_QOS_SEL_DATA_SCTP, M2PA_PPI, M2PA_DATA_STREAM, };// ptrace(("%x, sending DATACK\n",(uint)m2)); if ( (mp = allocb(3*sizeof(uint32_t), BPRI_MED)) ) { mp->b_datap->db_type = M_DATA; *((uint32_t *)mp->b_wptr)++ = M2PA_DATACK_MESSAGE; *((uint32_t *)mp->b_wptr)++ = __constant_htonl(3*sizeof(uint32_t)); *((uint32_t *)mp->b_wptr)++ = htonl(count); if ( !(err = n_exdata_req(m2, &qos, sizeof(qos), mp)) ) return(0); assert(mp->b_datap->db_ref); freeb(mp); return(err); } return(-ENOBUFS);}/* * M2PA SEND DATA * --------------------------------------------- */static intm2pa_send_data(m2pa_t *m2, mblk_t *dp){ int err; mblk_t *mp, *db; ulong rcpt = m2->version<M2PA_VERSION_DRAFT4?N_RC_FLAG:0; size_t dlen = dp->b_wptr - dp->b_rptr; N_qos_sel_data_sctp_t qos = { N_QOS_SEL_DATA_SCTP, M2PA_PPI, M2PA_DATA_STREAM, };// ptrace(("%x, sending DATA length = %u\n",(uint)m2,dlen)); if ( !(db = dupmsg(dp)) ) return(-ENOBUFS); if ( (mp = allocb(2*sizeof(uint32_t), BPRI_MED)) ) { mp->b_datap->db_type = M_DATA; *((uint32_t *)mp->b_wptr)++ = M2PA_DATA_MESSAGE; *((uint32_t *)mp->b_wptr)++ = __constant_htonl(dlen + 2*sizeof(uint32_t)); mp->b_cont = db; pullupmsg(mp, -1); if ( !(err = n_data_req(m2, rcpt, &qos, sizeof(qos), mp)) ) { if ( rcpt ) m2->dacks++; return(0); } assert(mp->b_datap->db_ref); freemsg(mp); return(err); } freemsg(db); return(-ENOBUFS);}/* * M2PA SEND * --------------------------------------------- */static intm2pa_send(m2pa_t *m2, mblk_t *dp){ int err; ulong rcpt = N_RC_FLAG; uint status; uint acks = 0; size_t dlen = dp->b_wptr - dp->b_rptr; size_t plen = 0; unsigned char *rptr = dp->b_rptr; if ( m2->version >= M2PA_VERSION_DRAFT4 ) { rcpt = 0; plen = 2*sizeof(uint32_t); } if ( m2->options.popt & SS7_POPT_XSN ) { if ( dlen < 6 ) { rare(); return(-EMSGSIZE); } switch ( dlen ) { case 6: status = M2PA_FISU;#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status && m2->version < M2PA_VERSION_DRAFT4 ) return(0);#endif m2->bsnt = ntohs(((uint16_t *)dp->b_rptr)[0])&0xfff; m2->fsnt = ntohs(((uint16_t *)dp->b_rptr)[1])&0xfff; acks = (m2->bsnt - m2->bsna)&0xfff; break; case 7: status = dp->b_rptr[6];#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status ) return(0);#endif break; case 8: status = dp->b_rptr[7];#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status ) return(0);#endif break; default: status = M2PA_MSU; m2->bsnt = ntohs(((uint16_t *)dp->b_rptr)[0])&0xfff; m2->fsnt = ntohs(((uint16_t *)dp->b_rptr)[1])&0xfff; acks = (m2->bsnt - m2->bsna)&0xfff; dp->b_rptr += 5; dlen -= 5; break; } } else { if ( dlen < 3 ) { rare(); return(-EMSGSIZE); } switch ( dlen ) { case 3: status = M2PA_FISU;#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status && m2->version < M2PA_VERSION_DRAFT4 ) return(0);#endif m2->bsnt = dp->b_rptr[0]&0x7f; m2->fsnt = dp->b_rptr[1]&0x7f; acks = (m2->bsnt - m2->bsna)&0x7f; break; case 4: status = dp->b_rptr[3];#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status ) return(0);#endif break; case 5: status = dp->b_rptr[4];#ifdef M2PA_TX_COMPRESSION if ( status == m2->tx_status ) return(0);#endif break; default: status = M2PA_MSU; m2->bsnt = dp->b_rptr[0]&0x7f; m2->fsnt = dp->b_rptr[1]&0x7f; acks = (m2->bsnt - m2->bsna)&0x7f; dp->b_rptr += 2; dlen -= 2; break; } } if ( m2->tx_status == M2PA_LSSU_SIPO && ( status == M2PA_FISU || status == M2PA_MSU ) ) { if ( (err = m2pa_send_status(m2, M2PA_STATUS_PROCESSOR_ENDED)) ) { dp->b_rptr = rptr; return(err); } } switch ( status ) { case M2PA_FISU: if ( m2->tx_status != M2PA_FISU && m2->tx_status != M2PA_MSU ) { if ( (err = m2pa_send_status(m2, M2PA_STATUS_IN_SERVICE)) ) return(err); break; } if ( m2->version < M2PA_VERSION_DRAFT4 ) break; if ( acks ) { if ( (err = m2pa_send_datack(m2, acks)) ) return(err); m2->bsna = m2->bsnt; } break; case M2PA_LSSU_SIO: if ( (err = m2pa_send_status(m2, M2PA_STATUS_ALIGNMENT)) ) return(err); break; case M2PA_LSSU_SIN: if ( (err = m2pa_send_status(m2, M2PA_STATUS_PROVING_NORMAL)) ) return(err); break; case M2PA_LSSU_SIE: if ( (err = m2pa_send_status(m2, M2PA_STATUS_PROVING_EMERGENCY)) ) return(err); break; case M2PA_LSSU_SIOS: if ( (err = m2pa_send_status(m2, M2PA_STATUS_OUT_OF_SERVICE)) ) return(err); break; case M2PA_LSSU_SIPO: if ( (err = m2pa_send_status(m2, M2PA_STATUS_PROCESSOR_OUTAGE)) ) return(err); break; case M2PA_LSSU_SIB: untimeout(xchg(&m2->timer_tx_sib,0)); m2->timer_tx_sib = timeout(&m2pa_tx_sib_timeout, (caddr_t)m2, M2PA_TX_SIB_TIME); if ( !(m2->flags & M2PA_FLAG_TX_BUSY) ) { m2->flags |= M2PA_FLAG_TX_BUSY; if ( (err = m2pa_send_status(m2, M2PA_STATUS_BUSY)) ) return(err); } break; case M2PA_MSU: if ( (err = m2pa_send_data(m2, dp)) ) { dp->b_rptr = rptr; return(err); } if ( acks ) { if ( (err = m2pa_send_datack(m2, acks)) ) return(err); m2->bsna = m2->bsnt; } break; } m2->tx_status = status; return(0);}/* * M2PA DELIV FISU * - - - - - - - - - - - - - - - - - - - - - - - * This function delivers a FISU to the SDL User. */static intm2pa_deliver_fisu(m2pa_t *m2, ulong count){ int err; mblk_t *mp; uint bsnr = m2->bsnr; uint fsnr = m2->fsnr;// ptrace(("%x, delivering FISU\n",(uint)m2)); if ( m2->options.popt & SS7_POPT_XSN ) { if ( (mp = allocb(6, BPRI_MED)) ) { bsnr &= 0xfff; fsnr &= 0xfff; *mp->b_wptr++ = (bsnr>> 0); *mp->b_wptr++ = (bsnr>> 8) | 0x80; *mp->b_wptr++ = (fsnr>> 0); *mp->b_wptr++ = (fsnr>> 8) | 0x80; *mp->b_wptr++ = 0; *mp->b_wptr++ = 0; } } else { if ( (mp = allocb(3, BPRI_MED)) ) { bsnr &= 0x7f; fsnr &= 0x7f; *mp->b_wptr++ = bsnr | 0x80; *mp->b_wptr++ = fsnr | 0x80; *mp->b_wptr++ = 0; } } if ( mp ) { mp->b_datap->db_type = M_DATA; if ( !(err = sdl_read(m2, mp)) ) return(0);// if ( !(err = sdl_daedr_received_bits_ind(m2, count, mp)) )// return(0); assert(mp->b_datap->db_ref); freeb(mp); return(err); } rare(); return(-ENOBUFS);}/* * M2PA DELIV LSSU * - - - - - - - - - - - - - - - - - - - - - - - * This function delivers an LSSU to the SDL User. */static intm2pa_deliver_lssu(m2pa_t *m2, ulong count, uint8_t status){ int err; mblk_t *mp; uint bsnr = m2->bsnr; uint fsnr = m2->fsnr;#if 0 { const char *r; switch ( status ) { case M2PA_LSSU_SIO: r = "SIO"; break; case M2PA_LSSU_SIN: r = "SIN"; break; case M2PA_LSSU_SIE: r = "SIE"; break; case M2PA_LSSU_SIOS: r = "SIOS"; break; case M2PA_LSSU_SIPO: r = "SIPO"; break; case M2PA_LSSU_SIB: r = "SIB"; break; default: r = "???"; break; } ptrace(("%x, delivering LSSU status = %s\n",(uint)m2, r)); }#endif if ( m2->options.popt & SS7_POPT_XSN ) { ptrace(("*******ERRROR: I'm not testing XSN!\n")); if ( (mp = allocb(7, BPRI_MED)) ) { bsnr &= 0xfff; fsnr &= 0xfff; *mp->b_wptr++ = (bsnr>> 0); *mp->b_wptr++ = (bsnr>> 8) | 0x80; *mp->b_wptr++ = (fsnr>> 0); *mp->b_wptr++ = (fsnr>> 8) | 0x80; *mp->b_wptr++ = 1; *mp->b_wptr++ = 0; *mp->b_wptr++ = status; } } else { if ( (mp = allocb(4, BPRI_MED)) ) { bsnr &= 0x7f; fsnr &= 0x7f; *mp->b_wptr++ = bsnr | 0x80; *mp->b_wptr++ = fsnr | 0x80; *mp->b_wptr++ = 1; *mp->b_wptr++ = status; } } if ( mp ) { mp->b_datap->db_type = M_DATA; if ( !(err = sdl_read(m2, mp)) ) return(0);// if ( !(err = sdl_daedr_received_bits_ind(m2, count, mp)) )// return(0); assert(mp->b_datap->db_ref);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -