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


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



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

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

#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 "../debug.h"
#include "../bufq.h"

#include "../ua/ua_data.h"
#include "../ua/ua_msg.h"
//#include "../ua/ua_sm.h"

/*
 *  =========================================================================
 *
 *  UA Peer --> UA (SGP) Received Messages
 *
 *  =========================================================================
 *
 *  These are procedures for common UA received messages at the SGP.
 */

/*
 *  ASPS ASPUP
 *  -------------------------------------------------------------------------
 *  ASP Identifier	Optional (But must be used sometimes)
 *  ASP Capabilities	Optional
 *  Info String		Optional
 */
static int ua_recv_aspup_req(sgp_t * sgp, mblk_t * mp)
{
	pp_t *pp = (pp_t *) q->q_ptr;
	sp_t *sp = pp->u.sp;
	mblk_t *rp;
	struct ua_parm *aspid = &ua_parm_results.aspid;
	struct ua_parm *asp_caps = &ua_parm_results.asp_caps;
	ua_decode_parms(mp);
	if (!aspid->u.wptr) {
		if (!sp || !sp->aspid) {
			if (!(rp = ua_mgmt_err(SUA_ECODE_REFUSED_ASP_IDENTIFIER_REQUIRED)))
				return (-ENOBUFS);
			qreply(q, rp);
			return (-EINVAL);
		}
	} else {
		if (sp) {
			if (sp->lp || (sp->aspid && sp->aspid != aspid->val)) {
				if (!(rp = ua_mgmt_err(SUA_ECODE_ERROR_INVALID_ASP_IDENTIFIER)))
					return (-ENOBUFS);
				qreply(q, rp);
				return (-EINVAL);
			}
		} else {
			for (sp = asp_head; sp && sp->aspid != aspid->val; sp = sp->next);
			if (!sp)
				for (sp = sgp_head; sp && sp->aspid != aspid->val; sp = sp->next);
			if (!sp)
				for (sp = spp_head; sp && sp->aspid != aspid->val; sp = sp->next);
			if (!sp || sp->lp) {
				if (!(rp = ua_mgmt_err(SUA_ECODE_ERROR_INVALID_ASP_IDENTIFIER)))
					return (-ENOBUFS);
				qreply(q, rp);
				return (-EINVAL);
			}
			pp->u.sp = sp;
			sp->lp = pp;
		}
		sp->aspid = aspid->val;

	}
	if (!asp_caps->u.wptr) {
		if (sp->asp_caps)
			*(asp_caps->u.wptr) = htonl(sp->asp_caps);
	} else {
		if (sp->asp_caps) {
			if (sp->asp_caps != asp_caps->val)
				*(asp_caps->u.wptr) = htonl(sp->asp_caps);
		} else
			sp->asp_caps = asp_caps->val;
	}
	sp->state = ASP_STATE_INACTIVE;
	if ((err = asp_recalc_as_state(sp)))
		return (err);
	*((long *) mp->b_rptr) = SUA_ASPS_ASPUPAC;
	qreply(q, mp);
	return (0);
}

/*
 *  ASPS ASPDN
 *  -------------------------------------------------------------------------
 */
static int ua_recv_aspdn_req(sgp_t * sgp, mblk_t * mp)
{
	/* 
	 *  This ASP is toast.  Return ASPDN Ack and mark ASP_STATE_DOWN.
	 *  Recalculate AS status.
	 */
	freemsg(mp);
	return (0);
}

/*
 *  ASPS HBEAT
 *  -------------------------------------------------------------------------
 *  Heartbeat Data	Optional
 */
static int ua_recv_hbeat_req(sgp_t * sgp, mblk_t * mp)
{
	/* 
	 *  This is a simple matter of turning around the heartbeat request.
	 *  We can just jam the message type and send it back.  Don't even
	 *  pull out the parameters.
	 */
	(void) q;
	(void) mp;
	return (-EOPNOTSUPP);
}

/*
 *  ASPS HBEAT Ack
 *  -------------------------------------------------------------------------
 *  Heartbeat Data	Optional
 */
static int ua_recv_hbeat_ack(sgp_t * sgp, mblk_t * mp)
{
	/* 
	 *  Check the heartbeat data.  There are a number of occasions for
	 *  which we send heartbeats.  There is a process waiting for the
	 *  response based on the heartbeat data or there is not.  This needs
	 *  be done in parallel for some applications (changeback).  We should
	 *  have a process list with ids from the data.  That way we could use
	 *  the data to index the function to call here...
	 *
	 *  Well..., normally we do this to flush an routing context traffic
	 *  flow.  If there is heartbeat data, extract the routing contexts
	 *  out of the heartbeat data and find AS in the AS_WACK_BEAT state.
	 */
	(void) q;
	(void) mp;
	return (-EOPNOTSUPP);
}

/*
 *  ASPT ASPAC
 *  -------------------------------------------------------------------------
 *  Traffic Mode Type	Mandatory
 *  Routing Context	Optional
 *  INFO String		Optional
 */
static int ua_recv_aspac_req(sgp_t * sgp, mblk_t * mp)
{
	int i;
	struct ua_parm *rc = &ua_parm_results.rc;
	ua_decode_parm_results(mp);
	if (rc->u.wptr && rc->len > 4) {
		int i;
		uint32_t *p = rc->u.wptr;
		for (i = 0, p = rc->u.wptr; i < (rc->len / 4) - 1; i++, p++) {
			uint32_t rcval = ntohl(*p++);
			/* 
			 *  Perform the ASPAC procedures.  Traffic Mode is
			 *  mandatory, but I don't care when I know the mode
			 *  of the AS from configuration data.  We must return
			 *  either en ASPAC Ack or an ERR.  Move the ASP to
			 *  active in the indicated AS.  Well..., just move
			 *  the ASP to the ASP-ACTIVE state and make sure that
			 *  we have the AS in the ASPs AS list.  Do a state
			 *  recalc on all the AS in the AS list.
			 */
		}
	} else {
	}
	freemsg(mp);
	return (0);
}

/*
 *  ASPT ASPIA
 *  -------------------------------------------------------------------------
 *  Routing Context	Optional
 *  INFO String		Optional
 */
static int ua_recv_aspia_req(sgp_t * sgp, mblk_t * mp)
{
	int i;
	struct ua_parm *rc = &ua_parms.rc;
	ua_decode_parms(mp);
	if (rc->u.wptr && rc->len > 4) {
		int i;
		uint32_t *p = rc->u.wptr;
		for (i = 0, p = rc->u.wptr; i < (rc->len / 4) - 1; i++, p++) {
			uint32_t rcval = ntohl(*p++);
			/* 
			 *  Check for AS which belong to the ASP by routing
			 *  context.  Place them in the state
			 *  AS_STATE_INACTIVE.  ALWAYS respond with an ASPIA
			 *  Ack.  Put it back if we can't.
			 */
		}
	} else {
	}
	freemsg(mp);
	return (0);
}

/*
 *  MGMT ERR
 *  -------------------------------------------------------------------------
 *  Error Code		Mandatory
 *  Diagnostic Info	Optional
 */
static int ua_recv_err(sgp_t * sgp, mblk_t * mp)
{
	sp_t *sp = ((pp_t *) q->q_ptr)->u.sp;
	ua_decode_parms(mp);
	if (!ua_parms.ecode.u.wptr)
		return -EINVAL;
	switch (ua_parms.ecode.val) {
		/* 
		 *  These values are from ua-07.
		 */
	case 0x01:		/* Invalid Version */
	case 0x05:		/* Unsupported Traffic Handling Mode */
	case 0x08:		/* Invalid Routing Context */
		/* 
		 *  If I am trying something, give up.
		 */
	case 0x0c:		/* Unexpected Parameter */
		/* 
		 *  TODO: Might be because we a using an extension
		 *  that the other end doesn't recognize.  Go after
		 *  the diagnostics parameter and see if we get the
		 *  parameter.  Then see if we can discover features
		 *  of the other end from which parameter was
		 *  unexpected.
		 */
	default:
	case 0x02:		/* n/a */
	case 0x03:		/* Unexpected Message Class */
	case 0x04:		/* Invalid Message Type Class */
	case 0x06:		/* Unexpected Message */
	case 0x07:		/* Protocol Error */
	case 0x09:		/* Invalid Stream Identifier */
	case 0x0b:		/* Parameter Field Error */
	case 0x0d:		/* Duplicated Parameter */
	case 0x0e:		/* Error - ASP Identifier Required */
	case 0x0f:		/* Error - Invalid ASP Identifier */
	case 0x10:		/* Refused - ASP Identifier Required */
		/* 
		 *  Some of these can't happen (we always send
		 *  optional fields).  Don't give up.
		 */
	}
	/* 
	 *  TODO: Notify management.
	 */
	freemsg(mp);
	return (0);
}

/*
 *  MGMT ERR
 *  -------------------------------------------------------------------------
 *  IMPLEMENTATION NOTE:-  We want to report all errors to management.  Some
 *  errors are considered fatal errors.  That is we will stop all processes,
 *  and put everything associated with the ASP/SGP/SP into the Down state,
 *  even drop the SCTP association.
 */
static int m3ua_err(sgp_t * sgp, mblk_t * mp)
{
	m3ua_parms_t parms;
	parm_t *ecode = &parms->common.ecode;
	parm_t *diag = &parms->common.diag;

	m3ua_decode_parms(msg, &parms);

	if (!ecode->u.wptr) {
		/* missing mandatory parameter */
		return (-EINVAL);
	}
	switch (*ecode->u.wptr) {
	case UA_ECODE_INVALID_VERSION:
	case UA_ECODE_INVALID_IID_OR_NTWK_APP:
	case UA_ECODE_UNSUPPORTED_MESSAGE_CLASS:
	case UA_ECODE_UNSUPPORTED_MESSAGE_TYPE:
	case UA_ECODE_UNSUPPORTED_TRAFFIC_MODE:
	case UA_ECODE_UNEXPECTED_MESSAGE:
	case UA_ECODE_PROTOCOL_ERROR:
	case UA_ECODE_INVALID_ROUTING_CONTEXT:
	case UA_ECODE_INVALID_STREAM_IDENTIFIER:
	case UA_ECODE_INVALID_PARAMETER_VALUE:
	case M3UA_ECODE_REFUSED_MANAGEMENT_BLOCKING:
	case M3UA_ECODE_UNKNOWN_ROUTING_CONTEXT:
	case M3UA_ECODE_INVALID_ASPID:
	default:
		/* error invalid error???? */
		return (-EINVAL);
	}

	return (-EOPNOTSUPP);
}

int (*ua_sgp_mgmt[]) (sgp_t *, mblk_t *) = {
	ua_recv_err,		/* UA_MGMT_ERR 0x0 */
	    NULL		/* UA_MGMT_NTFY 0x1 */
};
int (*ua_sgp_asps[]) (sgp_t *, mblk_t *) = {
	NULL,			/* (reserved) 0x0 */
	    ua_recv_aspup_req,	/* UA_ASPS_ASPUP_REQ 0x1 */
	    ua_recv_aspdn_req,	/* UA_ASPS_ASPDN_REQ 0x2 */
	    ua_recv_beat_req,	/* UA_ASPS_HBEAT_REQ 0x3 */
	    NULL,		/* UA_ASPS_ASPUP_ACK 0x4 */
	    NULL,		/* UA_ASPS_ASPDN_ACK 0x5 */
	    ua_recv_beat_ack	/* UA_ASPS_HBEAT_ACK 0x6 */
};
int (*ua_sgp_aspt[]) (sgp_t *, mblk_t *) = {
	NULL,			/* (reserved) 0x0 */
	    ua_recv_aspac_req,	/* UA_ASPT_ASPAC_REQ 0x1 */
	    ua_recv_aspia_req,	/* UA_ASPT_ASPIA_REQ 0x2 */
	    NULL,		/* UA_ASPT_ASPAC_ACK 0x3 */
	    NULL		/* UA_ASPT_ASPIA_ACK 0x4 */
};


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

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

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