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/sigtran/tua.c


File /code/strss7/drivers/sigtran/tua.c



#ident "@(#) $RCSfile: tua.c,v $ $Name:  $($Revision: 0.8.2.4 $) $Date: 2003/04/14 12:13:19 $"

static char const ident[] =
    "$RCSfile: tua.c,v $ $Name:  $($Revision: 0.8.2.4 $) $Date: 2003/04/14 12:13:19 $";

#include <linux/config.h>
#include <linux/version.h>
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>

#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/cmn_err.h>
#include <sys/dki.h>

#include "../debug.h"
#include "../bufq.h"

#define TUA_DESCRIP	"SIGTRAN TUA STREAMS MULTIPLEXING DRIVER."
#define TUA_COPYRIGHT	"Copyright (c) 1997-2002 OpenSS7 Corporation.  All Rights Reserved."
#define TUA_DEVICE	"Part of the OpenSS7 Stack for LiS STREAMS."
#define TUA_CONTACT	"Brian Bidulock <bidulock@openss7.org>"
#define TUA_LICENSE	"GPL"
#define TUA_BANNER	TUA_DESCRIP	"\n" \
			TUA_COPYRIGHT	"\n" \
			TUA_DEVICE	"\n" \
			TUA_CONTACT	"\n"

MODULE_AUTHOR(TUA_CONTACT);
MODULE_DESCRIPTION(TUA_DESCRIP);
MODULE_SUPPORTED_DEVICE(TUA_DEVICE);
#ifdef MODULE_LICENSE
MODULE_LICENSE(TUA_LICENSE);
#endif

#ifndef INT
#define INT void
#endif

/*
 *  =========================================================================
 *
 *  STREAMS Definitions
 *
 *  =========================================================================
 */

static int tua_open(queue_t *, dev_t *, int, int, cred_t *);
static int tua_close(queue_t *, int, cred_t *);

static struct module_info tua_m_minfo = {
	0,				/* Module ID number */
	"tua-lm",			/* Module name */
	0,				/* Min packet size accepted */
	INFPSZ,				/* Max packet size accepted */
	1,				/* Hi water mark */
	0				/* Lo water mark */
};

static INT tua_m_rput(queue_t *, mblk_t *);
static INT tua_m_rsrv(queue_t *);

static struct qinit tua_m_rinit {
	tua_m_rput,			/* Read put (msg from below) */
	tua_m_rsrv,			/* Read queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_m_minfo,			/* Information */
	NULL				/* Statistics */
};

static INT tua_m_wput(queue_t *, mblk_t *);
static INT tua_m_wsrv(queue_t *);

static struct qinit tua_m_winit {
	tua_m_wput,			/* Write put (msg from above) */
	tua_m_wsrv,			/* Write queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_m_minfo,			/* Information */
	NULL				/* Statistics */
};

static struct module_info tua_u_minfo = {
	0,				/* Module ID number */
	"tua-slu",			/* Module name */
	0,				/* Min packet size accepted */
	INFPSZ,				/* Max packet size accepted */
	1,				/* Hi water mark */
	0				/* Lo water mark */
};

static INT tua_u_rput(queue_t *, mblk_t *);
static INT tua_u_rsrv(queue_t *);

static struct qinit tua_u_rinit {
	tua_u_rput,			/* Read put (msg from below) */
	tua_u_rsrv,			/* Read queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_u_minfo,			/* Information */
	NULL				/* Statistics */
};

static INT tua_u_wput(queue_t *, mblk_t *);
static INT tua_u_wsrv(queue_t *);

static struct qinit tua_u_winit {
	tua_u_wput,			/* Write put (msg from above) */
	tua_u_wsrv,			/* Write queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_u_minfo,			/* Information */
	NULL				/* Statistics */
};

static struct module_info tua_l_info = {
	0,				/* Module ID number */
	"tua-slp",			/* Module name */
	0,				/* Min packet size accepted */
	INFPSZ,				/* Max packet size accepted */
	1,				/* Hi water mark */
	0				/* Lo water mark */
};

static INT tua_l_rput(queue_t *, mblk_t *);
static INT tua_l_rsrv(queue_t *);

static struct qinit tua_l_rinit {
	tua_l_rput,			/* Read put (msg from below) */
	tua_l_rsrv,			/* Read queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_l_info,			/* Information */
	NULL				/* Statistics */
};

static INT tua_l_wput(queue_t *, mblk_t *);
static INT tua_l_wsrv(queue_t *);

static struct qinit tua_l_winit {
	tua_l_wput,			/* Write put (msg from above) */
	tua_l_wsrv,			/* Write queue service */
	tua_open,			/* Each open */
	tua_close,			/* Last close */
	NULL,				/* Admin (not used) */
	&tua_l_info,			/* Information */
	NULL				/* Statistics */
};

static struct streamtab tua_m_info = {
	&tua_m_rinit,			/* Upper read queue */
	&tua_m_winit,			/* Upper write queue */
	&tua_l_rinit,			/* Lower read queue */
	&tua_l_winit			/* Lower write queue */
};

static struct streamtab tua_u_info = {
	&tua_u_rinit,			/* Upper read queue */
	&tua_u_winit,			/* Upper write queue */
	&tua_l_rinit,			/* Lower read queue */
	&tua_l_winit			/* Lower write queue */
};

/*
 *  =========================================================================
 *
 *  OUTPUT Events
 *
 *  =========================================================================
 */
/*
 *  TUA --> LM Primitives
 *  -----------------------------------
 */
int lm_ok_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	lm_ok_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_OK_ACK;

		putq(ua->rq, mp);
	}
	return (rtn);
}

int lm_error_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	lm_error_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_ERROR_ACK;

		putq(ua->rq, mp);
	}
	return (rtn);
}

int lm_reg_ind(ua_t * ua, mblk_t * mp)
{
	int rtn;
	lm_reg_ind_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_REG_IND;

		putq(ua->rq, mp);
	}
	return (rtn);
}

int lm_dereg_ind(ua_t * ua, mblk_t * mp)
{
	int rtn;
	lm_dereg_ind_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_DEREG_IND;

		putq(ua->rq, mp);
	}
	return (rtn);
}

int lm_error_ind(ua_t * ua, mblk_t * mp)
{
	int rtn;
	lm_error_ind_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_ERROR_IND;

		putq(ua->rq, mp);
	}
	return (rtn);
}

/*
 *  TUA --> SCCPP Primitives
 *  -----------------------------------
 */
static int n_info_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_info_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_INFO_ACK;

		putq(ua->wq, mp);
	}
	return (rtn);
}
static int n_bind_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_bind_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_BIND_ACK;

		putq(ua->wq, mp);
	}
	return (rtn);
}
static int n_error_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_error_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_ERROR_ACK;

		putq(ua->wq, mp);
	}
	return (rtn);
}
static int n_ok_ack(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_ok_ack_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_OK_ACK;

		putq(ua->wq, mp);
	}
	return (rtn);
}
static int n_unitdata_ind(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_unitdata_ind_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_UNITDATA_IND;

		putq(ua->wq, mp);
	}
	return (rtn);
}
static int n_uderror_ind(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_uderror_ind_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_UDERROR_IND;

		putq(ua->wq, mp);
	}
	return (rtn);
}

/*
 *  TUA --> SCCPU Primitives
 *  -----------------------------------
 */
static int n_info_req(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_info_req_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_INFO_REQ;

		putq(ua->rq, mp);
	}
	return (rtn);
}
static int n_bind_req(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_bind_req_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_BIND_REQ;

		putq(ua->rq, mp);
	}
	return (rtn);
}
static int n_unbind_req(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_unbind_req_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_UNBIND_REQ;

		putq(ua->rq, mp);
	}
	return (rtn);
}
static int n_unitdata_req(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_unitdata_req_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_UNITDATA_REQ;

		putq(ua->rq, mp);
	}
	return (rtn);
}
static int n_optmgmt_req(ua_t * ua, mblk_t * mp)
{
	int rtn;
	N_optmgmt_req_t *p;
	if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_OPTMGMT_REQ;

		putq(ua->rq, mp);
	}
	return (rtn);
}

/*
 *  =========================================================================
 *
 *  STREAMS Message Handling
 *
 *  =========================================================================
 */
/*
 *  -------------------------------------------------------------------------
 *
 *  Management Stream (LM) Message Handling
 *
 *  -------------------------------------------------------------------------
 */
/*
 *  LM --> TUA Primitives
 *  -----------------------------------
 */
int lm_as_add_req(queue_t * q, mblk_t * mp)
{
}
int lm_as_del_req(queue_t * q, mblk_t * mp)
{
}
int lm_proc_add_req(queue_t * q, mblk_t * mp)
{
}
int lm_proc_del_req(queue_t * q, mblk_t * mp)
{
}
int lm_link_add_req(queue_t * q, mblk_t * mp)
{
}
int lm_link_del_req(queue_t * q, mblk_t * mp)
{
}
int lm_route_add_req(queue_t * q, mblk_t * mp)
{
}
int lm_route_del_req(queue_t * q, mblk_t * mp)
{
}
int lm_reg_res(queue_t * q, mblk_t * mp)
{
}
int lm_reg_ref(queue_t * q, mblk_t * mp)
{
}
static int tua_m_w_ioctl(queue_t * q, mblk_t * mp)
{
}
static int tua_m_w_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case LM_AS_ADD_REQ:
		return lm_as_add_req(q, mp);
	case LM_AS_DEL_REQ:
		return lm_as_del_req(q, mp);
	case LM_PROC_ADD_REQ:
		return lm_proc_add_req(q, mp);
	case LM_PROC_DEL_REQ:
		return lm_proc_del_req(q, mp);
	case LM_LINK_ADD_REQ:
		return lm_link_add_req(q, mp);
	case LM_LINK_DEL_REQ:
		return lm_link_del_req(q, mp);
	case LM_ROUTE_ADD_REQ:
		return lm_route_add_req(q, mp);
	case LM_ROUTE_DEL_REQ:
		return lm_route - del_req(q, mp);
	case LM_REG_RES:
		return lm_reg_res(q, mp);
	case LM_REG_REF:
		return lm_reg_ref(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int tua_m_w_pcproto(queue_t * q, mblk_t * mp)
{
	return tua_m_w_proto(q, mp);
}
static int tua_m_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_PROTO:
		return tua_m_w_proto(q, mp);
	case M_PCPROTO:
		return tua_m_w_pcproto(q, mp);
	case M_IOCTL:
		return tua_m_w_ioctl(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}
static INT tua_m_wput(queue_t * q, mblk_t * mp)
{
	return ((INT) ua_putq(q, mp, &tua_m_w_prim));
}
static INT tua_m_wsrv(queue_t * q)
{
	return ((INT) ua_srvq(q, &tua_m_w_prim));
}

/*
 *  TUA --> LM Primitives
 *  -----------------------------------
 */
static int tua_m_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (5);
}
static INT tua_m_rput(queue_t * q, mblk_t * mp)
{
	return ((INT) ua_putq(q, mp, &tua_m_r_prim));
}
static INT tua_m_rsrv(queue_t * q)
{
	return ((INT) ua_srvq(q, &tua_m_r_prim));
}

/*
 *  -------------------------------------------------------------------------
 *
 *  SCCP User (SCCPU) Stream Message Handling
 *
 *  -------------------------------------------------------------------------
 */
/*
 *  TCAP User --> TUA Primitives
 *  -----------------------------------
 */
static int tcapu_info_req(queue_t * q, mblk_t * mp)
{
}
static int tcapu_bind_req(queue_t * q, mblk_t * mp)
{
}
static int tcapu_unbind_req(queue_t * q, mblk_t * mp)
{
}
static int tcapu_unitdata_req(queue_t * q, mblk_t * mp)
{
}
static int tcapu_optmgmt_req(queue_t * q, mblk_t * mp)
{
}
static int tua_u_w_ioctl(queue_t * q, mblk_t * mp)
{
}
static int tua_u_w_data(queue_t * q, mblk_t * dp)
{
	/* 
	 *  Need to convert data to SL_PDU_REQ.
	 */
	int rtn;
	mblk_t *mp;
	sl_pdu_req_t *p;
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_REQ;
		mp->b_cont = dp;
		switch ((rtn = slu_pdu_req(q, mp))) {
		}
		return (1);
	}
	return (-ENOBUFS);
}
static int tua_u_w_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b - rptr)) {
	case N_INFO_REQ:
		return tcapu_info_req(q, mp);
	case N_BIND_REQ:
		return tcapu_bind_req(q, mp);
	case N_UNBIND_REQ:
		return tcapu_unbind_req(q, mp);
	case N_UNITDATA_REQ:
		return tcapu_unitdata_req(q, mp);
	case N_OPTMGMT_REQ:
		return tcapu_optmgmt_req(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int tua_u_w_pcproto(queue_t * q, mblk_t * mp)
{
	return tua_u_w_proto(q, mp);
}
static int tua_u_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return tua_u_w_data(q, mp);
	case M_PROTO:
		return tua_u_w_proto(q, mp);
	case M_PCPROTO:
		return tua_u_w_pcproto(q, mp);
	case M_IOCTL:
		return tua_u_w_ioctl(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}
static INT tua_u_wput(queue_t * q, mblk_t * mp)
{
	return ((INT) ua_putq(q, mp, &tua_u_w_prim));
}
static INT tua_u_wsrv(queue_t * q)
{
	return ((INT) ua_srvq(q, &tua_u_w_prim));
}

/*
 *  TUA --> TCAP User Primitives
 *  -----------------------------------
 */
static int tua_u_r_data(queue_t * q, mblk_t * mp)
{
}
static int tua_u_r_ctl(queue_t * q, mblk_t * mp)
{
}
static int tua_u_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return tua_u_r_data(q, mp);
	case M_CTL:
		return tua_u_r_ctl(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (5);
}
static INT tua_u_rput(queue_t * q, mblk_t * mp)
{
	return ((INT) ua_putq(q, mp, &tua_u_r_prim));
}
static INT tua_u_rsrv(queue_t * q)
{
	return ((INT) ua_srvq(q, &tua_u_r_prim));
}

/*
 *  -------------------------------------------------------------------------
 *
 *  SCCP Provider (SCCPP) Stream Message Handling
 *
 *  -------------------------------------------------------------------------
 */
/*
 *  TUA --> TCAP Provider Primitives
 *  -----------------------------------
 */
static int tua_l_w_data(queue_t * q, mblk_t * mp)
{
}
static int tua_l_w_ctl(queue_t * q, mblk_t * mp)
{
}
static int tua_l_w_error(queue_t * q, mblk_t * mp)
{
}
static int tua_l_w_hangup(queue_t * q, mblk_t * mp)
{
}
static int tua_l_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return tua_l_w_data(q, mp);
	case M_CTL:
		return tua_l_w_ctl(q, mp);
	case M_ERROR:
		return tua_l_w_error(q, mp);
	case M_HANGUP:
		return tua_l_w_hangup(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (5);
}
static INT tua_l_wput(queue_t * q, mblk_t * mp)
{
	return ((INT) ua_putq(q, mp, &tua_l_w_prim));
}
static INT tua_l_wsrv(queue_t * q)
{
	return ((INT) ua_srvq(q, &tua_l_w_prim));
}

/*
 *  TCAP Provider --> TUA Primitives
 *  -----------------------------------
 */
static int tcapp_uni_ind(queue_t * q, mblk_t ** mpp);
{
	mblk_t *mp;
	TC_uni_ind_t *p = (typeof(p)) (*mpp)->b_rptr;
	tcap_addr_t *src = (typeof(src)) (*mpp)->b_rptr + p->SRC_offset;
	tcap_addr_t *dst = (typeof(dst)) (*mpp)->b_rptr + p->DEST_offset;
	TC_qos_sel_data_t *qos = (typeof(qos)) (dst + 1);
	size_t mlen = *sizeof(uint32_t);
	size_t dlen = msgdsize((*mpp)->b_cont);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DEST_ADDR;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_ORIG_ADDR;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_APPL_CTXT;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_USER_INFO;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_CONFIDENT;
		*((uint32_t *) mp->b_wptr)++ = TUA_PARM_SECU_CNTX;

	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int tcapp_begin_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_begin_con(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_cont_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_end_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_abort_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_notice_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG;
	*((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS;
}
static int tcapp_invoke_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
}
static int tcapp_result_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
}
static int tcapp_error_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
}
static int tcapp_cancel_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
}
static int tcapp_reject_ind(queue_t * q, mblk_t ** mpp);
{
	*((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_RC;
	*((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID;
}
static int tcapp_xlat_prim(queue_t * q, mblk_t ** mpp)
{
	switch (*((long *) (*mpp)->b_rptr)) {
	case TC_UNI_IND:
		return tcapp_uni_ind(q, mpp);
	case TC_BEGIN_IND:
		return tcapp_begin_ind(q, mpp);
	case TC_BEGIN_CON:
		return tcapp_begin_con(q, mpp);
	case TC_CONT_IND:
		return tcapp_cont_ind(q, mpp);
	case TC_END_IND:
		return tcapp_end_ind(q, mpp);
	case TC_ABORT_IND:
		return tcapp_abort_ind(q, mpp);
	case TC_NOTICE_IND:
		return tcapp_notice_ind(q, mpp);
	case TC_INVOKE_IND:
		return tcapp_invoke_ind(q, mpp);
	case TC_RESULT_IND:
		return tcapp_result_ind(q, mpp);
	case TC_ERROR_IND:
		return tcapp_error_ind(q, mpp);
	case TC_CANCEL_IND:
		return tcapp_cancel_ind(q, mpp);
	case TC_REJECT_IND:
		return tcapp_reject_ind(q, mpp);
	}
	return (-EOPNOTSUPP);
}
static int tcapp_xlat_prim(queue_t * q, mblk_t * mp)
{
	int err;
	xp_t *xp;
	pp_t *pp;
	as_t *as;
	lp_t *lp = (lp_t *) q->q_ptr;
	ensure(q, return (-EFAULT));
	ensure(lp, return (-EFAULT));
	if (lp->l.state != NS_IDLE)
		return (0);
	/* 
	 *  If we have a local TCAP User, then just pass the primitive on to
	 *  the local user.
	 */
	if ((pp = ua_as_route_loc(as))) {
		if (mp->b_datap->db_type < QPCTL && !canput(pp->rq))
			return (-EBUSY);
		putq(pp->rq, mp);
		return (1);
	}
	/* 
	 *  If we have a remote SCCP User (i.e, SUA AS), then translate the
	 *  primitive to an SUA messages and pass it to the AS>
	 */
	if ((xp = ua_as_route_rem(as))) {
		if (!(pp = xp->pp.pp)) {
			ptrace(("Have route to XP but no LP\n"));
			return (-EFAULT);
		}
		if (mp->b_datap->db_type < QPCTL && !caonput(pp->rq))
			return (-EBUSY);
		if ((err = tcapp_xlat(as, &mp)))
			return (err);
		putq(pp->rq, mp);
		return (1);
	}
	ptrace(("AS-U marked active but not AS-U\n"));
	return (-EFAULT);
}
static int tua_l_r_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case TC_INFO_ACK:
		return tcapp_info_ack(q, mp);
	case TC_BIND_ACK:
		return tcapp_bind_ack(q, mp);
	case TC_SUBS_BIND_ACK:
		return tcapp_subs_bind_ack(q, mp);
	case TC_OK_ACK:
		return tcapp_ok_ack(q, mp);
	case TC_ERROR_ACK:
		return tcapp_error_ack(q, mp);
	case TC_OPTMGMT_ACK:
		return tcapp_optmgmt_ack(q, mp);
	case TC_UNI_IND:
	case TC_BEGIN_IND:
	case TC_BEGIN_CON:
	case TC_CONT_IND:
	case TC_END_IND:
	case TC_ABORT_IND:
	case TC_NOTICE_IND:
	case TC_INVOKE_IND:
	case TC_RESULT_IND:
	case TC_ERROR_IND:
	case TC_CANCEL_IND:
	case TC_REJECT_IND:
		return tcapp_xlat_prim(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int tua_l_r_pcproto(queue_t * q, mblk_t * mp)
{
	return tua_l_r_proto(q, mp);
}
static int tua_l_r_error(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down AS, notify LM.\n"));
	return (-EFAULT);
}
static int tua_l_r_hangup(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down AS, notify LM.\n"));
	return (-EFAULT);
}
static int tua_l_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_PROTO:
		return tua_l_r_proto(q, mp);
	case M_PCPROTO:
		return tua_l_r_pcproto(q, mp);
	case M_ERROR:
		return tua_l_r_error(q, mp);
	case M_HANGUP:
		return tua_l_r_hangup(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

/*
 *  -------------------------------------------------------------------------
 *
 *  SCTP NPI Transport Message Handling
 *
 *  -------------------------------------------------------------------------
 *
 *  TUA --> SCTP NPI Transport Primitives
 *  -------------------------------------------------------------------------
 */
static int tua_s_w_data(queue_t * q, mblk_t * dp)
{
	mblk_t *mp;
	N_data_req_t *p;
	N_qos_sel_data_sctp_t *q;
	if ((mp = allocb(sizeof(*p) + sizeof(*q), BPRI_MED))) {
		uint32_t mhdr = ((uint32_t *) dp->b_rptr)[0];
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_DATA_REQ;
		p->DATA_xfer_flags = 0;
		q = ((typeof(q)) mp->b_wptr)++;
		q->n_qos_type = N_QOS_SEL_DATA_SCTP;
		q->ppi = TUA_PPI;
		q->tsn = 0;
		q->ssn = 0;
		mp->b_cont = dp;
		switch (UA_MSG_CLAS(mhdr)) {
		case UA_CLASS_MGMT:
		case UA_CLASS_ASPS:
		case UA_CLASS_RKMM:
			q->sid = 0;
			break;
		case UA_CLASS_ASPT:
		case UA_CLASS_XFER:
		case UA_CLASS_SNMM:
		{
			uint32_t rc = ((uint32_t *) dp->b_rptr)[3];
			fixme(("Map RC onto a stream id\n"));
			q->sid = rc;
			break;
		}
		default:
		case UA_CLASS_MAUP:
		case UA_CLASS_Q921:
		case UA_CLASS_CNLS:
		case UA_CLASS_CONS:
		case UA_CLASS_TDHM:
		case UA_CLASS_TCHM:
			freeb(mp);
			return (-EPROTO);
		}
		putq(q, mp);
		return (1);
	}
	return (-ENOBUFS);
}
static int tua_s_w_ctl(queue_t * q, mblk_t * mp)
{
	return tua_s_w_data(q, mp);
}
static int tua_s_w_error(queue_t * q, mblk_t * mp)
{
	fixme(("Disconnect, deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int tua_s_w_hangup(queue_t * q, mblk_t * mp)
{
	fixme(("Disconnect, deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int tua_x_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return tua_s_w_data(q, mp);
	case M_CTL:
		return tua_s_w_ctl(q, mp);
	case M_ERROR:
		return tua_s_w_error(q, mp);
	case M_HANGUP:
		return tua_s_w_hangup(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

/*
 *  SCTP NPI Transport --> TUA Primitives
 *  -------------------------------------------------------------------------
 */
static int tua_s_data_ind(queue_t * q, mblk_t * mp)
{
}
static int tua_s_exdata_ind(queue_t * q, mblk_t * mp)
{
}
static int tua_s_other_ind(queue_t * q, mblk_t * mp)
{
}
static int tua_s_r_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case N_DATA_IND:
		return tua_s_data_ind(q, mp);
	case N_EXDATA_IND:
		return tua_s_exdata_ind(q, mp);
	default:
		return tua_s_other_ind(q, mp);
	}
}
static int tua_s_r_pcproto(queue_t * q, mblk_t * mp)
{
	return tua_s_r_proto(q, mp);
}
static int tua_s_r_error(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int tua_s_r_hangup(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int tua_x_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_PROTO:
		return tua_s_r_proto(q, mp);
	case M_PCPROTO:
		return tua_s_r_pcproto(q, mp);
	case M_ERROR:
		return tua_s_r_error(q, mp);
	case M_HANGUP:
		return tua_s_r_hangup(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

extern struct drv tua_driver = {
	TUA_CMAJOR,
	TUA_NMAJOR,
	TUA_NMINOR,
	{&tua_u_r_prim, &tua_u_w_prim},
	{&tua_l_r_prim, &tua_l_w_prim},
	{&tua_x_r_prim, &tua_x_w_prim}
};


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

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

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