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_lower.c


File /code/strss7/drivers/ua/ua_lower.c



#ident "@(#) $RCSfile: ua_lower.c,v $ $Name:  $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $"

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

#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 "ua.h"
#include "ua_data.h"

/*
 *  =========================================================================
 *
 *  SCCP/NPI/TPI --> SUA (Upstream Primitives received from downstream)
 *
 *  =========================================================================
 */

/* from ua_nsp.c */
extern int nsp_r_data(queue_t *, mblk_t *);
extern int nsp_r_proto(queue_t *, mblk_t *);

/* from ua_tsp.c */
extern int tsp_r_data(queue_t *, mblk_t *);
extern int tsp_r_proto(queue_t *, mblk_t *);

/* from ua_ss7.c *//* UA-specific */
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 spp_r_error(queue_t * q, mblk_t * msg)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	if ((err = ua_spp_blocked(q)))
		return (err);
	return (0);
}
static int ss7_r_error(queue_t * q, mblk_t * msg)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	if ((err = ua_ss7_blocked(q)))
		return (err);
	return (0);
}

/*
 *  M_CTL Processing
 *  -------------------------------------------------------------------------
 *  None of the SS7 or TSP support any M_CTL messages.  Notify management and
 *  ignore the message.
 */
static int xxx_r_ctl(queue_t * q, mblk_t * msg)
{
	int err;
	if ((err = lm_link_ind(q, mp)))
		return (err);
	return (0);
}

/*
 *  M_FLUSH Processing
 *  -------------------------------------------------------------------------
 *  Take flushes from below and turn them around back down to the SS7 or TSP
 *  provider.
 */
static int xxx_r_flush(queue_t * q, mblk_t * msg)
{
	if (*msg->b_rptr & FLUSHR) {
		if (*msg->b_rptr & FLUSHBAND)
			flushband(q, msg->b_rptr[1], FLUSHALL);
		else
			flushall(q, FLUSHALL);
		*msg->b_rptr &= ~FLUSHR;
	}
	if ((*msg->b_rptr & FLUSHW) && !(msg->b_flags & MSGNOLOOP)) {
		if (*msg->b_rptr & FLUSHBAND)
			flushband(q, msg->b_rptr[1], FLUSHALL);
		else
			flushall(q, FLUSHALL);
		msg->b_flag |= MSGNOLOOP;
		qreply(q, msg);	/* flush all the way back down */
	}
	freemsg(msg);
	return (0);
}

/*
 *  =========================================================================
 *
 *  QUEUE PUT and SERVICE routines
 *
 *  =========================================================================
 */

static inline int ua_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 ua_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 SCCP/NPI/TPI --> SUA)
 *  -------------------------------------------------------------------------
 */
static inline int ua_rd(queue_t * q, mblk_t * mp)
{
	switch (Q_TYPE(q)) {
	case Q_TYPE_NPI:
		switch (mp->b_datap->db_type) {
		case M_DATA:
			return nsp_r_data(q, mp);
		case M_PROTO:
		case M_PCPROTO:
			return nsp_r_proto(q, mp);
		case M_ERROR:
		case M_HANGUP:
			return spp_r_error(q, mp);
		case M_CTL:
			return xxx_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	case Q_TYPE_TPI:
		switch (mp->b_datap->db_type) {
		case M_DATA:
			return tsp_r_data(q, mp);
		case M_PROTO:
		case M_PCPROTO:
			return tsp_r_proto(q, mp);
		case M_ERROR:
		case M_HANGUP:
			return spp_r_error(q, mp);
		case M_CTL:
			return xxx_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	case Q_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 xxx_r_ctl(q, mp);
		case M_FLUSH:
			return xxx_r_flush(q, mp);
		}
		return (-EOPNOTSUPP);
	}
	return (-EFAULT);
}

INT ua_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 = ua_rd(q, mp)))
		return (INT) (ua_recover(q, mp, err));
	return (INT) (0);
}

INT ua_l_rsrv(queue_t * q)
{
	mblk_t *mp;
	while ((mp = getq(q))) {
		int err;
		if (!(err = ua_rd(q, mp)))
			continue;
		if (mp->b_datap->db_type < QPCTL)
			return (INT) (ua_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/ua/ua_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: