OpenSS7 SS7 for the Common Man |
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
||||||||||||||||||||||||||
Home | Overview | Status | News | Documentation | Resources | About | |||||||||||||||||||||
File /code/strss7/drivers/ua/lm_nsp.c#ident "@(#) $RCSfile: lm_nsp.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2002/10/18 02:26:19 $" static char const ident[] = "$RCSfile: lm_nsp.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2002/10/18 02:26:19 $"; /* * ========================================================================= * * NS-Provider --> UA (NS-User) Upstream Primitives * * ========================================================================= * This file handles all the messages received from the transport provider * (normally SCTP) which are either linked as ASP/SGP/SPP. */ /* * N_CONN_IND 11 * ------------------------------------------------------------------------- * The stream has connected. This normally only occurs when we are listening * on a specific port number and the maximum number of outstanding connection * indications is set to 1. In this case, we must be already configured by * the configuration daemon (i.e., we must be already associated with an SPP * structure.) Otherwise, we will refuse the connection. This should only * happen at an SGP or SPP. */ static int nsp_conn_ind(queue_t * q, mblk_t * pdu) { (void) q; (void) pdu; return (-EOPNOTSUPP); } /* * N_CONN_CON 12 * ------------------------------------------------------------------------- * The configuration daemon has sent the N_CONN_REQ, linked us and configured * us. This is just the confirmation coming back that the connection has * been successful. We do not inform management, we just change the state of * the interface. This should only happen at an ASP or SPP. */ static int nsp_conn_con(queue_t * q, mblk_t * pdu) { (void) q; (void) pdu; return (-EOPNOTSUPP); } /* * N_DISCON_IND 13 * ------------------------------------------------------------------------- * The connection is gone. We don't want to mess with the stream, let the * configuration daemon decide what to do with it. We notify management and * shut down the ASP/SGP/SPP associated with the stream. The configuration * daemon will have to unlink the stream to do anything with it, so we * disable the stream's queues. */ static int nsp_discon_ind(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_DATA_IND 14 * ------------------------------------------------------------------------- * This is a data indication. We use the PPI in the data indication (if * provided) to determine to which UA this message belongs or use the default * UA. If no UA is allocated, we put this back and disable the stream's * queues. We must perform reassembly here if required. */ static inline int nsp_rdata_ind(nsp_t * nsp, uint ppi, uint sid, uint ssn, uint tsn, mblk_t * dp) { spp_t *spp = NULL; switch (ppi) { case 0: spp = nsp->dflt; break; case N_QOS_PPI_M2UA: spp = nsp->m2ua; break; case N_QOS_PPI_M3UA: spp = nsp->m3ua; break; case N_QOS_PPI_SUA: spp = nsp->sua; break; case N_QOS_PPI_TUA: spp = nsp->tua; break; } if (spp) /* we have an SPP for this PPI */ return (*spp->recv) (q, dp); /* discard it */ return (-EOPNOTSUPP); } static int nsp_r_data(queue_t * q, mblk_t * pdu) { nsp_t *nsp = (nsp_t *) q->q_ptr; return nsp_rdata_ind(nsp, 0, 0, 0, 0, pdu); } static int nsp_data_ind(queue_t * q, mblk_t * pdu) { int err; mblk_t **rap; nsp_t *nsp = (nsp_t *) q->q_ptr; N_data_int_t *p = (N_data_ind_t *) pdu->b_rptr; uint ppi = 0, sid = 0, ssn = 0, tsn = 0; /* * Get stream specifics... */ if (p->QOS_length && p->QOS_offset) { N_qos_str_sel_sctp_t *q = (N_qos_str_sel_sctp_t *) (pdu->b_rptr + p->QOS_offset); if (q->n_qos_type == N_QOS_STR_SEL_SCTP) { ppi = q->ppi; sid = q->sid; ssn = q->ssn; tsn = q->tsn; } } /* * Do acknowledgement... */ if (p->DATA_xfer_flags & N_RC_FLAG) { mblk_t *rp; if (!(rp = n_datack_req(ppi, sid, ssn, tsn))) return (-ENOBUFS); qreply(q, rp); } /* * Do reassembly... */ switch (p->PRIM_type) { /* * FIXME: this should probably be done on a * per-stream id basis as well. */ case N_DATA_IND: rap = &nsp->nsdu_reassem; break; case N_EXDATA_IND: rap = &nsp->ensdu_reassem; break; default: return (-EFAULT); } if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) { if (*rap) { linkb(*rap, pdu->b_cont); freeb(pdu); } else { *rap = pdu; } return (0); } else { if (*rap) { linkb(*rap, pdu->b_cont); freeb(pdu); pdu = *rap; *rap = NULL; } } if ((err = nsp_rdata_ind(nsp, ppi, sid, ssn, tsn, pdu->b_cont))) return (err); freeb(pdu); return (0); } /* * N_EXDATA_IND 15 * ------------------------------------------------------------------------- * This is a data indication. We use the PPI in the data indication (if * provided) to determine to which UA this message belongs or use the default * UA. If no UA is allocated, we put this back and disable the stream's * queues. We must perform reassembly here if required. */ static int nsp_exdata_ind(queue_t * q, mblk_t * pdu) { return nsp_data_ind(q, pdu); } /* * N_INFO_ACK 16 * ------------------------------------------------------------------------- * This is an acknowledgement to our information request. We just copy * information from the ack into internal data structures. */ static int nsp_info_ack(queue_t * q, mblk_t * pdu) { nsp_t *nsp = (nsp_t *) q->q_ptr; N_info_ack_t *p = (N_info_ack_t *) pdu->b_rptr; nsp->vers = p->NPI_version; nsp->prov = p->PROVIDER_type; nsp->flags = p->OPTIONS_flags; nsp->serv = p->SERV_type; nsp->state = p->CURRENT_state; nsp->asize = p->ADDR_size; nsp->alen = p->ADDR_length; nsp->qlen = p->QOS_length; nsp->plen = p->PROTOID_length; bcopy(mp->b_rptr + p->ADDR_offset, nsp->addr, p->ADDR_length); bcopy(mp->b_rptr + p->QOS_offset, nsp->qos, p->QOS_length); bcopy(mp->b_rptr + p->PROTOID_offset, nsp->pid, p->PROTOID_length); nsp->nidu = p->NIDU_size; nsp->nodu = p->NODU_size; nsp->nsdu = p->NSDU_size; nsp->ensdu = p->ENSDU_size; nsp->cdata = p->CDATA_size; nsp->ddata = p->DDATA_size; freemsg(pdu); return (0); } /* * N_BIND_ACK 17 * ------------------------------------------------------------------------- * We should never receive this. It is an error. Inform management, * delete private structures, disable the stream and leave it to management * to deal with. */ static int nsp_bind_ack(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_ERROR_ACK 18 * ------------------------------------------------------------------------- * We should never receive this. It is an error. Inform management, * delete private structures, disable the stream and leave it to management * to deal with. */ static int nsp_error_ack(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_OK_ACK 19 * ------------------------------------------------------------------------- * We should never receive this. We move the appropriate state and discard * the message. */ static int nsp_ok_ack(queue_t * q, mblk_t * pdu) { (void) q; (void) pdu; return (-EOPNOTSUPP); } /* * N_UNITDATA_IND 20 * ------------------------------------------------------------------------- * We should never receive this. It is an error, put this back and error * out the stream. */ static int nsp_unitdata_ind(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_UDERROR_IND 21 * ------------------------------------------------------------------------- * We should never receive this. It is an error, put this back and error * out the stream. */ static int nsp_uderror_ind(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_DATACK_IND 24 * ------------------------------------------------------------------------- * Our sent data has been acknowledged. We can strike one data from our * retransmission buffer. */ static int nsp_datack_ind(queue_t * q, mblk_t * pdu) { (void) q; (void) pdu; return (-EOPNOTSUPP); } /* * N_RESET_IND 26 * ------------------------------------------------------------------------- * The queues should have been flushed before we receive this. We have * restarted. We should put this back and error out the stream. */ static int nsp_reset_ind(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } /* * N_RESET_CON 28 * ------------------------------------------------------------------------- * We should never receive this (we don't send N_RESET_REQ). We should * put this back and error out the stream. */ static int nsp_reset_con(queue_t * q, mblk_t * pdu) { int err; lp_t *lp = (lp_t *) q->q_ptr; (void) pdu; if ((err = lm_link_del_ind(lp))) return (err); (*lp->ops.delete) (lp); qdisable(q); return (-EAGAIN); } static int (*nsp_ustr_prim[]) (queue_t *, mblk_t *) = { NULL, /* N_CONN_REQ 0 */ NULL, /* N_CONN_RES 1 */ NULL, /* N_DISCON_REQ 2 */ NULL, /* N_DATA_REQ 3 */ NULL, /* N_EXDATA_REQ 4 */ NULL, /* N_INFO_REQ 5 */ NULL, /* N_BIND_REQ 6 */ NULL, /* N_UNBIND_REQ 7 */ NULL, /* N_UNITDATA_REQ 8 */ NULL, /* N_OPTMGMT_REQ 9 */ NULL, /* 10 */ #define NSP_USTR_FIRST N_CONN_IND nsp_conn_ind, /* N_CONN_IND 11 */ nsp_conn_con, /* N_CONN_CON 12 */ nsp_discon_ind, /* N_DISCON_IND 13 */ nsp_data_ind, /* N_DATA_IND 14 */ nsp_exdata_ind, /* N_EXDATA_IND 15 */ nsp_info_ack, /* N_INFO_ACK 16 */ nsp_bind_ack, /* N_BIND_ACK 17 */ nsp_error_ack, /* N_ERROR_ACK 18 */ nsp_ok_ack, /* N_OK_ACK 19 */ nsp_unitdata_ind, /* N_UNITDATA_IND 20 */ nsp_uderror_ind, /* N_UDERROR_IND 21 */ NULL, /* 22 */ NULL, /* N_DATACK_REQ 23 */ nsp_datack_ind, /* N_DATACK_IND 24 */ NULL, /* N_RESET_REQ 25 */ nsp_reset_ind, /* N_RESET_IND 26 */ NULL, /* N_RESET_RES 27 */ nsp_reset_con /* N_RESET_CON 28 */ #define NSP_USTR_LAST N_RESET_CON }; static int nsp_r_proto(queue_t * q, mblk_t * pdu) { } static int nsp_r_error(queue_t * q, mblk_t * pdu) { } static int nsp_r_hangup(queue_t * q, mblk_t * pdu) { } static int nsp_r_flush(queue_t * q, mblk_t * pdu) { return ua_r_flush(q, pdu); } static int (*nsp_r_ops[]) (queue_t *, mblk_t *) = { nsp_r_data, /* M_DATA */ nsp_r_proto, /* M_PROTO */ NULL, /* M_BREAK */ NULL, /* M_CTL */ NULL, /* M_DELAY */ NULL, /* M_IOCTL */ NULL, /* M_PASSFP */ NULL, /* M_RSE */ NULL, /* M_SETOPTS */ NULL, /* M_SIG */ NULL, /* M_COPYIN */ NULL, /* M_COPYOUT */ nsp_r_error, /* M_ERROR */ nsp_r_flush, /* M_FLUSH */ nsp_r_hangup, /* M_HANGUP */ NULL, /* M_IOCACK */ NULL, /* M_IOCNAK */ NULL, /* M_IOCDATA */ nsp_r_proto, /* M_PCPROTO */ NULL, /* M_PCRSE */ NULL, /* M_PCSIG */ NULL, /* M_READ */ NULL, /* M_STOP */ NULL, /* M_START */ NULL, /* M_STARTI */ NULL /* M_STOPI */ } static void nsp_l_create(lp_t * lp) { } static void nsp_l_delete(lp_t * lp) { } struct ops lm_nsp_l_ops = { &nsp_l_create, /* create priv struct */ &nsp_l_delete, /* delete priv struct */ &nsp_r_ops, /* read operations */ NULL /* write operations */ };
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |