OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/ua/ua_nsp.c


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);
}


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/ua/ua_nsp.c

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: