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/ua_nsp.c#ident "@(#) $RCSfile: ua_nsp.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2002/10/18 02:26:20 $" static char const ident[] = "$RCSfile: ua_nsp.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2002/10/18 02:26:20 $"; /* * ========================================================================= * * N-Provider --> UA (Upstream Primitives recevied from below) * * ========================================================================= */ /* * N_CONN_IND * ------------------------------------------------------------------------- * Inform management and force the asp down immediately, abort and unlink the * stream and let management deal with it. */ static int nsp_conn_ind(queue_t * q, mblk_t * pdu) { int err; /* notify management */ if ((err = m_link_ind(q, pdu))) return (err); if ((err = ua_sp_down(q))) return (err); /* * FIXME: abort and unlink the stream... */ return (0); } /* * N_CONN_CON * ------------------------------------------------------------------------- * Inform management and force the asp down immediately, abort and unlink the * stream and let management deal with it. */ static int nsp_conn_con(queue_t * q, mblk_t * pdu) { int err; /* notify management */ if ((err = m_link_ind(q, pdu))) return (err); if ((err = ua_sp_down(q))) return (err); /* * FIXME: abort and unlink the stream... */ return (0); } /* * N_DISCON_IND * ------------------------------------------------------------------------- * Inform management and force the asp down immediately; we don't have time * to wait for management to decide to do this for us; we unlink the stream * so that management can talk to the stream directly. */ static int nsp_discon_ind(queue_t * q, mblk_t * pdu) { int err; /* give it to management */ if ((err = m_link_ind(q, pdu))) return (err); if ((err = ua_sp_down(q))) return (err); /* * FIXME: unlink the stream... */ return (0); } /* * N_DATA_IND * ------------------------------------------------------------------------- * This is translated into UA messages and fed to the state machines. * FIXME: this function is not memory exhaustion safe... */ static int nsp_data_ind(queue_t * q, mblk_t * pdu) { int err; mblk_t *dp; sp_t *sp = ((lp_t *) q->q_ptr)->u.sp; N_data_ind_t *p = (N_data_ind_t *) pdu->b_rptr; if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) { /* reassembling data at the SP */ if (sp->reassem) linkb(sp->reassem, pdu->b_cont); else sp->reassem = pdu->b_cont; freeb(pdu); return (0); } if (p->DATA_xfer_flags & N_RC_FLAG) { /* we only ack complete NSDUs */ mblk_t *rp; if (!(rp = nsp_datack_ind())) return (-ENOBUFS); qreply(q, rp); } if (sp->reassem) { /* we are completing reassembly at the SP */ linkb(sp->reassem, pdu->b_cont); dp = sp->reassem; sp->reassem = NULL; } else { dp = pdu->b_cont; } dp->b_band = 0; if ((err = ua_recv_msg(q, mp))) return (err); freeb(pdu); return (0); } /* * N_EXDATA_IND * ------------------------------------------------------------------------- * This is translated into UA messages and fed to the state machines. * FIXME: this function is not memory exhaustion safe... */ static int nsp_exdata_ind(queue_t * q, mblk_t * pdu) { int err; mblk_t *dp; sp_t *sp = ((lp_t *) q->q_ptr)->u.sp; N_data_ind_t *p = (N_data_ind_t *) pdu->b_rptr; if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) { /* reassembling exdata at the SP */ if (sp->exassem) linkb(sp->exassem, pdu->b_cont); else sp->exassem = pdu->b_cont; freeb(pdu); return (0); } if (p->DATA_xfer_flags & N_RC_FLAG) { /* we only ack complete NSDUs */ mblk_t *rp; if (!(rp = nsp_datack_ind())) return (-ENOBUFS); qreply(q, rp); } if (sp->exassem) { /* we are completing reassembly at the SP */ linkb(sp->exassem, pdu->b_cont); dp = sp->exassem; sp->exassem = NULL; } else { dp = pdu->b_cont; } dp->b_band = 1; if ((err = ua_recv_msg(q, mp))) return (err); freeb(pdu); return (0); } /* * N_INFO_ACK * ------------------------------------------------------------------------- */ static int nsp_info_ack(queue_t * q, mblk_t * pdu) { /* * NOTE:- We might later want to copy out some of the pertinent * information for ourselves. */ /* give it to management */ return m_link_ind(q, pdu); } /* * N_BIND_ACK * ------------------------------------------------------------------------- */ static int nsp_bind_ack(queue_t * q, mblk_t * pdu) { /* * NOTE:- We might later want to copy out some of the pertinent * information for ourselves. */ /* give it to management */ return m_link_ind(q, pdu); } /* * N_ERROR_ACK * ------------------------------------------------------------------------- */ static int nsp_error_ack(queue_t * q, mblk_t * pdu) { /* * FIXME: We should check what state we are in and decide what * actions should be taken. Most often we will probably need to shut * down the SP, abort the connection and unlink the stream. */ /* give it to management */ return m_link_ind(q, pdu); } /* * N_OK_ACK * ------------------------------------------------------------------------- */ static int nsp_ok_ack(queue_t * q, mblk_t * pdu) { /* * FIXME: We should check what state we are in and decide what * actions should be taken. Most often we will probably need to shut * down the SP, abort the connection and unlink the stream. */ /* give it to management */ return m_link_ind(q, pdu); } /* * N_UNITDATA_IND * ------------------------------------------------------------------------- * I don't know why we would get these, but maybe this is a connection-less * transport which is sequenced... */ static int nsp_unitdata_ind(queue_t * q, mblk_t * pdu) { int err; mblk_t *dp; dp = pdu->b_cont; dp->b_band = 0; freeb(pdu); if ((err = ua_recv_msg(q, dp))) return (err); return (0); } /* * N_UDERROR_IND * ------------------------------------------------------------------------- * I don't know why we would get these but they are bad... */ static int nsp_uderror_ind(queue_t * q, mblk_t * pdu) { int err; if ((err = m_link_ind(q, mp))) return (err); if ((err = ua_sp_down(q))) return (err); qdisable(q); return (0); } /* * N_DATACK_IND * ------------------------------------------------------------------------- * If we've got receipt confirmation enabled we need to strike a message from * our fail-over buffer. It is better if the underlying layer supports * retrieval instead (that way we can distinguish between sent and unsent * unacknolwedged messages to avoid duplication). * * We don't suport this yet... */ static int nsp_datack_ind(queue_t * q, mblk_t * pdu) { (void) q; (void) pdu; return (-EOPNOTSUPPORT); } /* * N_RESET_IND * ------------------------------------------------------------------------- * We have lost and resetalished communication. This results from an SCTP * Restart or from an SSCOP Reset. The N-Provider should have flushed the * read queue up to us. We should have responded to that an flushed read * queues to the SCCP-Users, however, we also need to place the state of the * ASP into the down state so that everything is in a known state. */ static int nsp_reset_ind(queue_t * q, mblk_t * pdu) { if ((err = m_link_ind(q, mp))) return (err); if ((err = ua_sp_down(q))) return (err); /* * FIXME: Perhaps we should be sending the N_RESET_CON back to the * peer to indicate that we have reset. Also, we should flush the * write queues. */ return (0); } /* * N_RESET_CON * ------------------------------------------------------------------------- * Same as N_RESET_IND, but Layer Management must have provoked it. */ static int nsp_reset_con(queue_t * q, mblk_t * pdu) { if ((err = m_link_ind(q, mp))) return (err); if ((err = ua_sp_down(q))) return (err); return (0); } static int (*nsp_prim[]) (queue_t *, mblk_t *) = { NULL, /* N_CONN_REQ */ NULL, /* N_CONN_RES */ NULL, /* N_DISCON_REQ */ NULL, /* N_DATA_REQ */ NULL, /* N_EXDATA_REQ */ NULL, /* N_INFO_REQ */ NULL, /* N_BIND_REQ */ NULL, /* N_UNBIND_REQ */ NULL, /* N_UNITDATA_REQ */ NULL, /* N_OPTMGMT_REQ */ NULL, /* (unused) */ nsp_conn_ind, /* N_CONN_IND */ nsp_conn_con, /* N_CONN_CON */ nsp_discon_ind, /* N_DISCON_IND */ nsp_data_ind, /* N_DATA_IND */ nsp_exdata_ind, /* N_EXDATA_IND */ nsp_info_ack, /* N_INFO_ACK */ nsp_bind_ack, /* N_BIND_ACK */ nsp_error_ack, /* N_ERROR_ACK */ nsp_ok_ack, /* N_OK_ACK */ nsp_unitdata_ind, /* N_UNITDATA_IND */ nsp_uderror_ind, /* N_UDERROR_IND */ NULL, /* (unused) */ NULL, /* N_DATACK_REQ */ nsp_datack_ind, /* N_DATACK_IND */ NULL, /* N_RESET_REQ */ nsp_reset_ind, /* N_RESET_IND */ NULL, /* N_RESET_RES */ nsp_reset_con /* N_RESET_CON */ }; /* * ========================================================================= * * M_DATA Processing * * ========================================================================= */ int nsp_r_data(queue_t * q, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * ========================================================================= * * M_PROTO, M_PCPROTO Processing * * ========================================================================= */ int nsp_r_proto(queue_t * q, mblk_t * msg) { int prim = *((t_scalar_t *) msg->b_rptr); if (0 <= prim && prim < sizeof(nsp_prim) / sizeof(int (*)(void)) && nsp_prim[prim]) return ((*nsp_prim[prim]) (q, msg)); return (-EOPNOTSUPP); } /* * ========================================================================= * * M_CTL Processing * * ========================================================================= */ int nsp_r_ctl(queue_t * q, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * ========================================================================= * * M_ERROR Processing * * ========================================================================= * This transport stream is toast. We have to inform management that this * transport stream (with this muxid) has errored out. We need to inform the * AS or SG that this SGP or ASP is dead and let the AS or SG recalculate the * state of the AS(s) associated with this transport stream. */ int nsp_r_error(queue_t * q, mblk_t * msg) { int err; sp_t *sp = ((lp_t *) q->q_ptr)->u.sp; switch (msg->b_wptr - msg->b_rptr) { case 1: sp->r_error = msg->b_rptr[0]; sp->w_error = msg->b_rptr[0]; break; case 2: sp->r_error = msg->b_rptr[0]; sp->w_error = msg->b_rptr[1]; break; } if ((err = m_link_ind(q, msg))) return (err); if ((err = ua_sp_down(q))) return (err); qdisable(q); return (0); } /* * ========================================================================= * * M_HANGUP Processing * * ========================================================================= */ int nsp_r_hangup(queue_t * q, mblk_t * msg) { int err; sp_t *sp = ((lp_t *) q->q_ptr)->u.sp; sp->r_error = 0; sp->w_error = 0; if ((err = m_link_ind(q, msg))) return (err); if ((err = ua_sp_down(q))) return (err); qdisable(q); return (0); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |