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/m3ua/m3ua_lower.c


File /code/strss7/drivers/m3ua/m3ua_lower.c



#ident "@(#) $RCSfile: m3ua_lower.c,v $ $Name:  $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:31 $"

static char const ident[] =
    "$RCSfile: m3ua_lower.c,v $ $Name:  $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:31 $";

#define __NO_VERSION__

#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 "m3ua.h"
#include "m3ua_data.h"

/*
 *  =========================================================================
 *
 *  Lower --> SUA (Upstream Primitives received from downstream)
 *
 *  =========================================================================
 */

/* from m3ua_uap.c */
extern int uap_r_data(queue_t *, mblk_t *);
extern int uap_r_proto(queue_t *, mblk_t *);

/* from m3ua_ss7.c */
extern int ss7_r_data(queue_t *, mblk_t *);
extern int ss7_r_proto(queue_t *, mblk_t *);

/*
 *  M_ERROR, M_HANGUP Processing
 *  -------------------------------------------------------------------------
 */
static int uap_r_error(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	if ((err = uap_blocked(q)))
		return (err);
	return (0);
}
static int ipc_r_error(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	if ((err = ipc_blocked(q)))
		return (err);
	return (0);
}
static int ss7_r_error(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	if ((err = ss7_blocked(q)))
		return (err);
	return (0);
}

/*
 *  M_CTL Processing
 *  -------------------------------------------------------------------------
 */
static int uap_r_ctl(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	return (0);
}
static int ipc_r_ctl(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	return (0);
}
static int ss7_r_ctl(queue_t * q, mblk_t * mp)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	return (0);
}

/*
 *  M_FLUSH Processing
 *  -------------------------------------------------------------------------
 */
static int xxx_r_flush(queue_t * q, mblk_t * mp)
{
	if (*mp->b_rptr & FLUSHR) {
		if (*mp->b_rptr & FLUSHBAND)
			flushband(q, mp->b_rptr[1], FLUSHALL);
		else
			flushall(q, FLUSHALL);
		*mp->b_rptr &= ~FLUSHR;
	}
	if ((*mp->b_rptr & FLUSHW) && !(mp->b_flags & MSGNOLOOP)) {
		if (*mp->b_rptr & FLUSHBAND)
			flushband(q, mp->b_rptr[1], FLUSHALL);
		else
			flushall(q, FLUSHALL);
		mp->b_flag |= MSGNOLOOP;
		qreply(q, mp);	/* flush all the way back down */
	}
	freemsg(mp);
	return (0);
}

/*
 *  =========================================================================
 *
 *  QUEUE PUT and SERVICE routines
 *
 *  =========================================================================
 */
static inline int m3ua_recover(queue_t * q, mblk_t * mp, int err)
{
	switch (err) {
	case -EBUSY:
	case -EAGAIN:
	case -ENOMEM:
	case -ENOBUFS:
		putq(q, mp);
		return (0);
	}
	freemsg(mp);
	return (err);
}
static inline int m3ua_reservice(queue_t * q, mblk_t * mp, int err)
{
	if (mp->b_datap->db_type < QPCTL)
		switch (err) {
		case -EBUSY:
		case -EAGAIN:
		case -ENOMEM:
		case -ENOBUFS:
			putbq(q, mp);
			return (0);
		}
	freemsg(mp);
	return (err);
}

/*
 *  READ PUT and SERVICE (Message from below to SUA)
 *  -------------------------------------------------------------------------
 */
static inline int m3ua_rd(queue_t * q, mblk_t * mp)
{
	switch (Q_TYPE(q)) {
	case UA_TYPE_UAP:
		switch (mp->b_datap->db_type) {
		case M_DATA:
			return uap_r_data(q, mp);
		case M_PROTO:
		case M_PCPROTO:
			return uap_r_proto(q, mp);
		case M_ERROR:
		case M_HANGUP:
			return uap_r_error(q, mp);
		case M_CTL:
			return uap_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	case UA_TYPE_IPC:
		switch (mp->b_datap->db_type) {
		case M_DATA:
			return ipc_r_data(q, mp);
		case M_PROTO:
		case M_PCPROTO:
			return ipc_r_proto(q, mp);
		case M_ERROR:
		case M_HANGUP:
			return ipc_r_error(q, mp);
		case M_CTL:
			return ipc_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	case UA_TYPE_SS7:
		switch (mp->b_datap->db_type) {
		case M_DATA:
			return ss7_r_data(q, mp);
		case M_PROTO:
		case M_PCPROTO:
			return ss7_r_proto(q, mp);
		case M_ERROR:
		case M_HANGUP:
			return ss7_r_error(q, mp);
		case M_CTL:
			return ss7_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	}
	return (-EFAULT);
}

INT m3ua_l_rput(queue_t * q, mblk_t * mp)
{
	int err;
	if (mp->b_datap->db_type < QPCTL && (q->q_count || !canputnext(q))) {
		putq(q, mp);
		return (INT) (0);
	}
	if ((err = m3ua_rd(q, mp)))
		return (INT) (m3ua_recover(q, mp, err));
	return (INT) (0);
}

INT m3ua_l_rsrv(queue_t * q)
{
	mblk_t *mp;
	while ((mp = getq(q))) {
		int err;
		if (!(err = m3ua_rd(q, mp)))
			continue;
		if (mp->b_datap->db_type < QPCTL)
			return (INT) (m3ua_reservice(q, mp, err));
		freemsg(mp);
		return (INT) (err);
	}
	return (INT) (0);
}


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

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

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