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/lm_nsp.c


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 */
};


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/ua/lm_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: