⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tirdwr.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** @(#) tirdwr.c,v LiS-2_16_18-8(1.1.1.2.8.2) 2004/01/29 14:11:44 ----------------------------------------------------------------------------- Copyright (c) 2001-2004  OpenSS7 Corporation <http://www.openss7.com> Copyright (c) 1997-2000  Brian F. G. Bidulock <bidulock@openss7.org> All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS.  If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you.  If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users).  If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any success regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Commercial licensing and support of this software is available from OpenSS7 Corporation at a fee.  See http://www.openss7.com/ ----------------------------------------------------------------------------- Last Modified 2004/01/29 14:11:44 by brian *****************************************************************************/#ident "@(#) tirdwr.c,v LiS-2_16_18-8(1.1.1.2.8.2) 2004/01/29 14:11:44"static char const ident[] =    "tirdwr.c,v LiS-2_16_18-8(1.1.1.2.8.2) 2004/01/29 14:11:44";#if defined(_LIS_SOURCE) && !defined(MODULE)#   error ****#   error ****  tirdwr can only compile as a module under LiS.#   error ****  This is normally because LiS has been grossly misconfigured.#   error ****  Report bugs to <bugs@openss7.org>.#   error ****#endif#include <linux/config.h>#include <linux/version.h>#ifdef CONFIG_MODVERSIONS#include <linux/modversions.h>#endif#include <linux/module.h>#include <linux/init.h>#include <sys/stream.h>#include <sys/cmn_err.h>/*   These are for TPI definitions  */#if defined HAVE_TIHDR_H#   include <tihdr.h>#else#   include <sys/tihdr.h>#endif// #define TIRDWR_PEDANTIC// #define TIRDWR_TPI_PEDANTIC#define TIRDWR_DESCRIP		"UNIX SYSTEM V RELEASE 4.2 FAST STREAMS FOR LINUX"#define TIRDWR_COPYRIGHT	"Copyright (c) 1997-2004 OpenSS7 Corporation.  All Rights Reserved."#define TIRDWR_REVISION		"LfS tirdwr.c,v LiS-2_16_18-8(1.1.1.2.8.2) 2004/01/29 14:11:44"#define TIRDWR_DEVICE		"SVR 4.2 STREAMS Read Write Module for XTI/TLI Devices (TIRDWR)"#define TIRDWR_CONTACT		"Brian Bidulock <bidulock@openss7.org>"#define TIRDWR_LICENSE		"GPL"#define TIRDWR_BANNER		TIRDWR_DESCRIP		"\n" \				TIRDWR_COPYRIGHT	"\n" \				TIRDWR_REVISION		"\n" \				TIRDWR_DEVICE		"\n" \				TIRDWR_CONTACT		"\n"#define TIRDWR_SPLASH		TIRDWR_DEVICE		" - " \				TIRDWR_REVSISIONMODULE_AUTHOR(TIRDWR_CONTACT);MODULE_DESCRIPTION(TIRDWR_DESCRIP);MODULE_SUPPORTED_DEVICE(TIRDWR_DEVICE);MODULE_LICENSE(TIRDWR_LICENSE);/* *  ========================================================================= * *  STREAMS Definitions * *  ========================================================================= */#ifndef TIRDWR_MOD_NAME#   ifdef CONFIG_STREAMS_TIRDWR_NAME#	define TIRDWR_MOD_NAME CONFIG_STREAMS_TIRDWR_NAME#   else#	define TIRDWR_MOD_NAME "tirdwr"#   endif#endif#ifndef TIRDWR_MOD_ID#   ifdef CONFIG_STREAMS_TIRDWR_MODID#	define TIRDWR_MOD_ID CONFIG_STREAMS_TIRDWR_MODID#   else#	define TIRDWR_MOD_ID 0#   endif#endifstatic modID_t modid = TIRDWR_MOD_ID;MODULE_PARM(modid, "b");MODULE_PARM_DESC(modid, "Module ID for TIRDWR.");static struct module_info tirdwr_minfo = {	mi_idnum:TIRDWR_MOD_ID,		/* Module ID number */	mi_idname:TIRDWR_MOD_NAME,	/* Module name */	mi_minpsz:0,			/* Min packet size accepted */	mi_maxpsz:INFPSZ,		/* Max packet size accepted */	mi_hiwat:1,			/* Hi water mark */	mi_lowat:0,			/* Lo water mark */};static int tirdwr_open(queue_t *, dev_t *, int, int, cred_t *);static int tirdwr_close(queue_t *, int, cred_t *);static int tirdwr_rput(queue_t *q, mblk_t *mp);static int tirdwr_wput(queue_t *q, mblk_t *mp);static struct qinit tirdwr_rinit = {	qi_putp:tirdwr_rput,		/* Read put (message from below) */	qi_qopen:tirdwr_open,		/* Each open */	qi_qclose:tirdwr_close,		/* Last close */	qi_minfo:&tirdwr_minfo,		/* Information */};static struct qinit tirdwr_winit = {	qi_putp:tirdwr_wput,		/* Write put (message from above) */	qi_minfo:&tirdwr_minfo,		/* Information */};static struct streamtab tirdwr_info = {	st_rdinit:&tirdwr_rinit,	/* Upper read queue */	st_wrinit:&tirdwr_winit,	/* Upper write queue */};/* *  ========================================================================= * *  Private Datastructure ctors and dtors * *  ========================================================================= *//*   LiS does not define these...  */#if !defined(HAVE_BCID_T)typedef int bcid_t;#endif#if !defined(HAVE_BUFCALL_ID_T)typedef int bufcall_id_t;#endiftypedef struct tirdwr {	queue_t *rq;			/* module read queue */	queue_t *wq;			/* module write queue */	queue_t *hq;			/* stream head read queue */	ulong state;			/* module state */	ulong flags;			/* module flags */	bcid_t rdzero_bcid;		/* bufcall id for sending zero length M_DATA */	bcid_t hangup_bcid;		/* bufcall id for sending M_HANGUP */	bcid_t eproto_bcid;		/* bufcall id for sending M_ERROR */} tirdwr_t;static kmem_cache_t *tirdwr_priv_cachep = NULL;static inttirdwr_init_caches(void){	if (!tirdwr_priv_cachep &&	    !(tirdwr_priv_cachep =	      kmem_cache_create(TIRDWR_MOD_NAME, sizeof(tirdwr_t), 0, SLAB_HWCACHE_ALIGN,				NULL, NULL))) {		cmn_err(CE_WARN, "%s: %s: Cannot allocate tirdwr_priv_cachep",			TIRDWR_MOD_NAME, __FUNCTION__);		return (-ENOMEM);	}	return (0);}static voidtirdwr_term_caches(void){	if (tirdwr_priv_cachep) {		if (kmem_cache_destroy(tirdwr_priv_cachep))			cmn_err(CE_WARN, "%s: %s: did not destroy tirdwr_priv_cachep",				TIRDWR_MOD_NAME, __FUNCTION__);	}	return;}static tirdwr_t *tirdwr_alloc_priv(queue_t *q){	tirdwr_t *priv;	if ((priv = kmem_cache_alloc(tirdwr_priv_cachep, SLAB_ATOMIC))) {		priv->rq = q;		priv->wq = WR(q);		priv->hq = q->q_next;		priv->state = TS_DATA_XFER;	/* assume we are in the correct initial state */		priv->flags = 0;		priv->rdzero_bcid = 0;		priv->hangup_bcid = 0;		priv->eproto_bcid = 0;		/*		   we are a module with no service routine so our hiwat, lowat shouldn't matter;		   however, our minpsz, maxpsz do because we are the first queue under the stream		   head.  We do not want to alter the characteristics of the transport packet sizes		   so we copy them here. This will allow the stream head to exhibit the same		   behaviour as before we were pushed. 		 */		priv->wq->q_minpsz = priv->wq->q_next->q_minpsz;		priv->wq->q_maxpsz = priv->wq->q_next->q_maxpsz;		q->q_ptr = WR(q)->q_ptr = priv;	}	return (priv);}static voidtirdwr_free_priv(queue_t *q){	tirdwr_t *priv;	if ((priv = (typeof(priv)) q->q_ptr)) {		if (priv->rdzero_bcid)			unbufcall(xchg(&priv->rdzero_bcid, 0));		if (priv->hangup_bcid)			unbufcall(xchg(&priv->hangup_bcid, 0));		if (priv->eproto_bcid)			unbufcall(xchg(&priv->eproto_bcid, 0));		q->q_ptr = WR(q)->q_ptr = NULL;		priv->rq = NULL;		priv->wq = NULL;		priv->hq = NULL;		priv->state = TS_IDLE;		priv->flags = 0;		kmem_cache_free(tirdwr_priv_cachep, priv);	}	return;}/* *  ========================================================================= * *  Messages and Buffer Calls * *  ========================================================================= */static void tirdwr_rdzero_bc(long arg);static void tirdwr_hangup_bc(long arg);static void tirdwr_eproto_bc(long arg);#define TIRDWR_HANGUP	01#define TIRDWR_EPROTO	02static voidtirdwr_rdzero(tirdwr_t * priv, mblk_t *mp, mblk_t *bp){	if (bp)		freemsg(bp);	if (mp)		freemsg(mp);	if (!(priv->flags & (TIRDWR_HANGUP | TIRDWR_EPROTO))) {		if (priv->rdzero_bcid != 0)			unbufcall(xchg(&priv->rdzero_bcid, 0));		if ((mp = allocb(0, BPRI_HI))) {			mp->b_datap->db_type = M_DATA;			putnext(priv->rq, mp);			return;		}		if (!(priv->rdzero_bcid = bufcall(0, BPRI_HI, &tirdwr_rdzero_bc, (long) priv)))			cmn_err(CE_WARN, "%s: could not allocate rdzero buffer call");	}}static voidtirdwr_hangup(tirdwr_t * priv, mblk_t *mp, mblk_t *bp){	if (bp)		freemsg(bp);	if (mp)		freemsg(mp);	if (!(priv->flags & (TIRDWR_HANGUP | TIRDWR_EPROTO))) {		if (priv->hangup_bcid != 0)			unbufcall(xchg(&priv->hangup_bcid, 0));		/*		   LiS does not have a reliable putnextctl() 		 */		if ((mp = allocb(0, BPRI_HI))) {			mp->b_datap->db_type = M_HANGUP;			/*			   LiS doesn't have a reliable putnext() either :/ 			 */			putnext(priv->rq, mp);			priv->flags |= TIRDWR_HANGUP;			return;		}		if (!(priv->hangup_bcid = bufcall(0, BPRI_HI, &tirdwr_hangup_bc, (long) priv)))			cmn_err(CE_WARN, "%s: could not allocate hangup buffer call");	}}static voidtirdwr_eproto(tirdwr_t * priv, mblk_t *mp, mblk_t *bp){	if (bp)		freemsg(bp);	if (mp)		freemsg(mp);	if (!(priv->flags & TIRDWR_EPROTO)) {		if (priv->eproto_bcid != 0)			unbufcall(xchg(&priv->eproto_bcid, 0));		if ((mp = allocb(2, BPRI_HI))) {			mp->b_datap->db_type = M_ERROR;			*(mp->b_wptr)++ = EPROTO;			*(mp->b_wptr)++ = EPROTO;			putnext(priv->rq, mp);			priv->flags |= TIRDWR_EPROTO;			return;		}		if (!(priv->eproto_bcid = bufcall(2, BPRI_HI, &tirdwr_eproto_bc, (long) priv)))			cmn_err(CE_WARN, "%s: could not allocate eproto buffer call");	}}static voidtirdwr_rdzero_bc(long arg){	tirdwr_t *priv = (typeof(priv)) arg;	if (xchg(&priv->rdzero_bcid, 0) != 0)		tirdwr_hangup((tirdwr_t *) arg, NULL, NULL);}static voidtirdwr_hangup_bc(long arg){	tirdwr_t *priv = (typeof(priv)) arg;	if (xchg(&priv->hangup_bcid, 0) != 0)		tirdwr_hangup((tirdwr_t *) arg, NULL, NULL);}static voidtirdwr_eproto_bc(long arg){	tirdwr_t *priv = (typeof(priv)) arg;	if (xchg(&priv->eproto_bcid, 0) != 0)		tirdwr_eproto((tirdwr_t *) arg, NULL, NULL);}/* *  ========================================================================= * *  PUT routines * *  ========================================================================= */static inline voidtirdwr_restore_delim(t_uscalar_t flag, mblk_t *mp){#if !defined TIRDWR_PEDANTIC	/*	   Although SVR 4 documentation says that we ignore message delimitors, we restore message	   delimitors in case the RMSGN or RMSGD read options are set at the stream head. Otherwise	   they are ignored anyway. 	 */	if (flag)		mp->b_flag &= ~MSGDELIM;	else		mp->b_flag |= MSGDELIM;#endif	return;}static inttirdwr_rput(queue_t *q, mblk_t *mp){	tirdwr_t *priv = (typeof(priv)) q->q_ptr;	mblk_t *bp = NULL;#if defined _LIS_SOURCE	if (q->q_next == NULL || OTHER(q)->q_next == NULL) {		cmn_err(CE_WARN, "%s: %s: LiS pipe bug: called with null q->q_next pointer.",			TIRDWR_MOD_NAME, __FUNCTION__);		freemsg(mp);		return (0);	}#endif				/* defined _LIS_SOURCE */	switch (mp->b_datap->db_type) {	case M_DATA:		/*		   There is a problem here right off the bat.  Although a TPI compliant provider		   must accept M_DATA written (instead of T_DATA_REQ), it should not generate		   M_DATA on read.  These should only be T_DATA_IND.  tirdwr can be pushed over		   other modules, however, and an underlying module (e.g. timod) might be stripping 		   T_DATA_IND blocks, so we process them anyway. 		 */#	    if !defined TIRDWR_TPI_PEDANTIC		if (mp->b_band == 0) {			if (msgdsize(mp) > 0) {				putnext(q, mp);			} else {				/*				   Silently discard zero length normal data. 				 */				freemsg(mp);			}		} else#	    endif		/* defined TIRDWR_TPI_PEDANTIC */			tirdwr_eproto(priv, mp, bp);		break;	case M_PCPROTO:#	    if defined TIRDWR_TPI_PEDANTIC		/*		   We could be forgiving and accept M_PCPROTO mesages that should actually be sent		   as M_PROTO messages; however, a transport service provider that sends M_PCPROTO		   for data or disconnect messages is in violation of the TPI specifications. 		 */		tirdwr_eproto(priv, mp, bp);		break;#	    endif		/* defined TIRDWR_TPI_PEDANTIC */	case M_PROTO:	{		union T_primitives *p = (typeof(p)) mp->b_rptr;		if (mp->b_wptr < mp->b_rptr + sizeof(p->type)) {			tirdwr_eproto(priv, mp, bp);			break;		}		switch (p->type) {		case T_DATA_IND:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -